diff options
1159 files changed, 83472 insertions, 62450 deletions
diff --git a/.github/workflows/android_builds.yml b/.github/workflows/android_builds.yml index 143f3961cf..697600abe3 100644 --- a/.github/workflows/android_builds.yml +++ b/.github/workflows/android_builds.yml @@ -6,6 +6,7 @@ env: GODOT_BASE_BRANCH: master SCONSFLAGS: platform=android verbose=yes warnings=extra werror=yes --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/linux_builds.yml b/.github/workflows/linux_builds.yml index 89e8f4d146..f4c377b921 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -8,9 +8,9 @@ env: 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" diff --git a/.github/workflows/static_checks.yml b/.github/workflows/static_checks.yml index da3327246b..12270a848a 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) 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/ @@ -116,6 +116,7 @@ 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> diff --git a/AUTHORS.md b/AUTHORS.md index 97c66a014c..1ebef77509 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) 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..b9b15abf5d 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,47 @@ 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 -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 +160,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 +172,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 +192,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 +249,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 +280,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 +308,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 +369,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 +386,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 +425,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 +577,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 +1873,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..065019d591 100644 --- a/SConstruct +++ b/SConstruct @@ -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 @@ -123,11 +122,12 @@ 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.", "") # 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)) @@ -308,7 +308,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 +317,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. We use `ARGUMENTS.get()` to check if they were manually set. if env["dev"]: - env["verbose"] = True - env["warnings"] = "extra" - env["werror"] = True + env["verbose"] = ARGUMENTS.get("verbose", True) + env["warnings"] = ARGUMENTS.get("warnings", "extra") + env["werror"] = ARGUMENTS.get("werror", True) if env["tools"]: - env["tests"] = True + env["tests"] = ARGUMENTS.get("tests", True) + if env["production"]: + env["use_static_cpp"] = ARGUMENTS.get("use_static_cpp", True) + env["use_lto"] = ARGUMENTS.get("use_lto", True) + env["debug_symbols"] = ARGUMENTS.get("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 = "" 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/core_bind.cpp b/core/core_bind.cpp index 46f05bdaf5..456a97e5e5 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -228,24 +228,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) { @@ -290,6 +298,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); } @@ -587,10 +599,7 @@ void _OS::print_resources_by_type(const Vector<String> &p_types) { List<Ref<Resource>> resources; ResourceCache::get_cached_resources(&resources); - List<Ref<Resource>> rsrc; - ResourceCache::get_cached_resources(&rsrc); - - for (List<Ref<Resource>>::Element *E = rsrc.front(); E; E = E->next()) { + for (List<Ref<Resource>>::Element *E = resources.front(); E; E = E->next()) { Ref<Resource> r = E->get(); bool found = false; @@ -700,7 +709,8 @@ 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); @@ -758,6 +768,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); @@ -1984,24 +1995,13 @@ Error _Thread::start(Object *p_instance, const StringName &p_method, const Varia 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 { @@ -2009,18 +2009,13 @@ bool _Thread::is_active() const { } 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); + thread.wait_to_finish(); Variant r = ret; active = false; target_method = StringName(); target_instance = nullptr; userdata = Variant(); - if (thread) { - memdelete(thread); - } - thread = nullptr; return r; } @@ -2036,10 +2031,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..3305c93089 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -155,8 +155,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); @@ -232,6 +232,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; @@ -553,7 +554,7 @@ protected: volatile bool active = false; Object *target_instance = nullptr; StringName target_method; - Thread *thread = nullptr; + Thread thread; static void _bind_methods(); static void _start_func(void *ud); @@ -569,9 +570,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/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/input/gamecontrollerdb.txt b/core/input/gamecontrollerdb.txt index 180708cea6..477e29808d 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,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,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,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,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,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, @@ -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,19 @@ 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, +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..2e3f112ebc 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -886,10 +886,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/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/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/ip.cpp b/core/io/ip.cpp index 6fb812e78d..df95785000 100644 --- a/core/io/ip.cpp +++ b/core/io/ip.cpp @@ -71,7 +71,7 @@ struct _IP_ResolverPrivate { Mutex mutex; Semaphore sem; - Thread *thread; + Thread thread; //Semaphore* semaphore; bool thread_abort; @@ -141,7 +141,7 @@ IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Typ } else { resolver->queue[id].response = IP_Address(); resolver->queue[id].status = IP::RESOLVER_STATUS_WAITING; - if (resolver->thread) { + if (resolver->thread.is_started()) { resolver->sem.post(); } else { resolver->resolve_queues(); @@ -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/resource.cpp b/core/io/resource.cpp index 716da5e395..db79998a90 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,9 +82,9 @@ 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"); @@ -315,9 +315,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 +323,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 +334,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 +368,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 +385,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 +399,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 +417,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 +445,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 +501,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..d0cd6ea3ac 100644 --- a/core/io/resource.h +++ b/core/io/resource.h @@ -149,16 +149,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..fad58d65fd 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; diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 821e468aee..d66511a39f 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -323,9 +323,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 +338,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 +362,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 +490,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); @@ -535,9 +532,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 +541,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 +552,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; @@ -955,9 +946,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 +956,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()) { 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..783750b9e6 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()); diff --git a/core/math/geometry_3d.cpp b/core/math/geometry_3d.cpp index a918d1de0d..a4a7463bfd 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; @@ -777,10 +777,11 @@ 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) { 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)); } @@ -805,10 +806,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)); @@ -835,10 +837,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/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 b121ef984a..60da6f5593 100644 --- a/core/math/transform.h +++ b/core/math/transform.h @@ -144,8 +144,8 @@ _FORCE_INLINE_ Plane Transform::xform(const Plane &p_plane) const { _FORCE_INLINE_ Plane Transform::xform_inv(const Plane &p_plane) const { Vector3 point = p_plane.normal * p_plane.d; Vector3 point_dir = point + p_plane.normal; - xform_inv(point); - xform_inv(point_dir); + point = xform_inv(point); + point_dir = xform_inv(point_dir); Vector3 normal = point_dir - point; normal.normalize(); 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..6b4ff3f9a8 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -324,48 +324,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/undo_redo.cpp b/core/object/undo_redo.cpp index c699820e75..3b1165b8f6 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"), &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/os.h b/core/os/os.h index ed3c6ddc94..e02ce7d5ec 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -129,7 +129,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); 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..936e5d5500 100644 --- a/core/os/thread.cpp +++ b/core/os/thread.cpp @@ -30,30 +30,70 @@ #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) + 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 = 1; +Thread::ID Thread::last_thread_id = 1; +thread_local Thread::ID Thread::caller_id = 1; -Thread::ID Thread::_main_thread_id = 0; +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; +} -Thread::ID Thread::get_caller_id() { - if (get_thread_id_func) { - return get_thread_id_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 = atomic_increment(&last_thread_id); + 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) { + thread.join(); + std::thread empty_thread; + thread.swap(empty_thread); + id = 0; } } @@ -64,3 +104,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..b5449d2ed6 100644 --- a/core/os/thread.h +++ b/core/os/thread.h @@ -31,13 +31,20 @@ #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 <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 +56,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 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..9538ac5957 100644 --- a/core/os/threaded_array_processor.h +++ b/core/os/threaded_array_processor.h @@ -74,18 +74,17 @@ void thread_process_array(uint32_t p_elements, C *p_instance, M p_method, U p_us data.elements = p_elements; data.process(data.index); //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 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/ustring.cpp b/core/string/ustring.cpp index 21336a99ec..0b6311dadf 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,11 +3071,16 @@ int String::rfindn(const String &p_str, int p_from) const { } bool String::ends_with(const String &p_string) const { + int l = p_string.length(); + if (l == 0) { + return true; + } + int pos = rfind(p_string); if (pos == -1) { return false; } - return pos + p_string.length() == length(); + return pos + l == length(); } bool String::begins_with(const String &p_string) const { @@ -3250,8 +3252,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 +3480,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 +3752,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 +3776,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()); @@ -4245,7 +4249,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 +4344,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/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.h b/core/templates/rid.h index 7fe6dbe473..4c7119b4ea 100644 --- a/core/templates/rid.h +++ b/core/templates/rid.h @@ -40,30 +40,37 @@ class RID { uint64_t _id = 0; public: - _FORCE_INLINE_ bool operator==(const RID &p_rid) const { + _ALWAYS_INLINE_ bool operator==(const RID &p_rid) const { return _id == p_rid._id; } - _FORCE_INLINE_ bool operator<(const RID &p_rid) const { + _ALWAYS_INLINE_ bool operator<(const RID &p_rid) const { return _id < p_rid._id; } - _FORCE_INLINE_ bool operator<=(const RID &p_rid) const { + _ALWAYS_INLINE_ bool operator<=(const RID &p_rid) const { return _id <= p_rid._id; } - _FORCE_INLINE_ bool operator>(const RID &p_rid) const { + _ALWAYS_INLINE_ bool operator>(const RID &p_rid) const { return _id > p_rid._id; } - _FORCE_INLINE_ bool operator>=(const RID &p_rid) const { + _ALWAYS_INLINE_ bool operator>=(const RID &p_rid) const { return _id >= p_rid._id; } - _FORCE_INLINE_ bool operator!=(const RID &p_rid) const { + _ALWAYS_INLINE_ bool operator!=(const RID &p_rid) const { return _id != p_rid._id; } - _FORCE_INLINE_ bool is_valid() const { return _id != 0; } - _FORCE_INLINE_ bool is_null() const { return _id == 0; } + _ALWAYS_INLINE_ bool is_valid() const { return _id != 0; } + _ALWAYS_INLINE_ bool is_null() const { return _id == 0; } - _FORCE_INLINE_ uint64_t get_id() const { return _id; } + _ALWAYS_INLINE_ uint32_t get_local_index() const { return _id & 0xFFFFFFFF; } - _FORCE_INLINE_ RID() {} + static _ALWAYS_INLINE_ RID from_uint64(uint64_t p_id) { + RID _rid; + _rid._id = p_id; + return _rid; + } + _ALWAYS_INLINE_ uint64_t get_id() const { return _id; } + + _ALWAYS_INLINE_ RID() {} }; #endif // RID_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 02d941d0f4..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> @@ -125,6 +125,7 @@ public: end_work(); } + _FORCE_INLINE_ int get_thread_count() const { return thread_count; } void init(int p_thread_count = -1); void finish(); ~ThreadWorkPool(); 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/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..8f2cba138b 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(" ")); @@ -1126,10 +1124,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 +1210,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()); @@ -1304,10 +1298,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/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp index caa0bfdbb1..f154ab1ed6 100644 --- a/core/variant/variant_utility.cpp +++ b/core/variant/variant_utility.cpp @@ -291,7 +291,7 @@ struct VariantUtilityFunctions { Variant ret; for (int i = 1; i < p_argcount; i++) { bool valid; - Variant::evaluate(Variant::OP_GREATER, base, *p_args[i], ret, valid); + Variant::evaluate(Variant::OP_LESS, base, *p_args[i], ret, valid); if (!valid) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.expected = base.get_type(); @@ -324,7 +324,7 @@ struct VariantUtilityFunctions { Variant ret; for (int i = 1; i < p_argcount; i++) { bool valid; - Variant::evaluate(Variant::OP_LESS, base, *p_args[i], ret, valid); + Variant::evaluate(Variant::OP_GREATER, base, *p_args[i], ret, valid); if (!valid) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.expected = base.get_type(); diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index c8f216e199..bf81362e79 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -668,7 +668,7 @@ </method> <method name="print" qualifiers="vararg"> <description> - Converts one or more arguments to strings in the best way possible and prints them to the console. + Converts one or more arguments of any type to string in the best way possible and prints them to the console. [codeblock] a = [1, 2, 3] print("a", "b", a) # Prints ab[1, 2, 3] @@ -944,6 +944,22 @@ [/codeblock] </description> </method> + <method name="snapped"> + <return type="float"> + </return> + <argument index="0" name="x" type="float"> + </argument> + <argument index="1" name="step" type="float"> + </argument> + <description> + Snaps float value [code]x[/code] to a given [code]step[/code]. This can also be used to round a floating point number to an arbitrary number of decimals. + [codeblock] + snapped(100, 32) # Returns 96 + snapped(3.14159, 0.01) # Returns 3.14 + [/codeblock] + See also [method ceil], [method floor], and [method round]. + </description> + </method> <method name="sqrt"> <return type="float"> </return> @@ -974,27 +990,11 @@ [/codeblock] </description> </method> - <method name="snapped"> - <return type="float"> - </return> - <argument index="0" name="x" type="float"> - </argument> - <argument index="1" name="step" type="float"> - </argument> - <description> - Snaps float value [code]x[/code] to a given [code]step[/code]. This can also be used to round a floating point number to an arbitrary number of decimals. - [codeblock] - snapped(100, 32) # Returns 96 - snapped(3.14159, 0.01) # Returns 3.14 - [/codeblock] - See also [method ceil], [method floor], and [method round]. - </description> - </method> <method name="str" qualifiers="vararg"> <return type="String"> </return> <description> - Converts one or more arguments to string in the best way possible. + Converts one or more arguments of any type to string in the best way possible. </description> </method> <method name="str2var"> diff --git a/doc/classes/AABB.xml b/doc/classes/AABB.xml index baea84df65..8cd7e6f5fa 100644 --- a/doc/classes/AABB.xml +++ b/doc/classes/AABB.xml @@ -219,7 +219,7 @@ <argument index="0" name="aabb" type="AABB"> </argument> <description> - Returns [code]true[/code] if this [AABB] and [code]aabb[/code] are approximately equal, by calling [method @GDScript.is_equal_approx] on each component. + Returns [code]true[/code] if this [AABB] and [code]aabb[/code] are approximately equal, by calling [method @GlobalScope.is_equal_approx] on each component. </description> </method> <method name="merge"> diff --git a/doc/classes/AStar.xml b/doc/classes/AStar.xml index 0cd7d3dc25..bfdc66623d 100644 --- a/doc/classes/AStar.xml +++ b/doc/classes/AStar.xml @@ -33,6 +33,7 @@ [/csharp] [/codeblocks] [method _estimate_cost] should return a lower bound of the distance, i.e. [code]_estimate_cost(u, v) <= _compute_cost(u, v)[/code]. This serves as a hint to the algorithm because the custom [code]_compute_cost[/code] might be computation-heavy. If this is not the case, make [method _estimate_cost] return the same value as [method _compute_cost] to provide the algorithm with the most accurate information. + If the default [method _estimate_cost] and [method _compute_cost] methods are used, or if the supplied [method _estimate_cost] method returns a lower bound of the cost, then the paths returned by A* will be the lowest cost paths. Here, the cost of a path equals to the sum of the [method _compute_cost] results of all segments in the path multiplied by the [code]weight_scale[/code]s of the end points of the respective segments. If the default methods are used and the [code]weight_scale[/code]s of all points are set to [code]1.0[/code], then this equals to the sum of Euclidean distances of all segments in the path. </description> <tutorials> </tutorials> @@ -71,7 +72,8 @@ <argument index="2" name="weight_scale" type="float" default="1.0"> </argument> <description> - Adds a new point at the given position with the given identifier. The algorithm prefers points with lower [code]weight_scale[/code] to form a path. The [code]id[/code] must be 0 or larger, and the [code]weight_scale[/code] must be 1 or larger. + Adds a new point at the given position with the given identifier. The [code]id[/code] must be 0 or larger, and the [code]weight_scale[/code] must be 1 or larger. + The [code]weight_scale[/code] is multiplied by the result of [method _compute_cost] when determining the overall cost of traveling across a segment from a neighboring point to this point. Thus, all else being equal, the algorithm prefers points with lower [code]weight_scale[/code]s to form a path. [codeblocks] [gdscript] var astar = AStar.new() @@ -380,7 +382,7 @@ <argument index="1" name="weight_scale" type="float"> </argument> <description> - Sets the [code]weight_scale[/code] for the point with the given [code]id[/code]. + Sets the [code]weight_scale[/code] for the point with the given [code]id[/code]. The [code]weight_scale[/code] is multiplied by the result of [method _compute_cost] when determining the overall cost of traveling across a segment from a neighboring point to this point. </description> </method> </methods> diff --git a/doc/classes/AStar2D.xml b/doc/classes/AStar2D.xml index 1540d8dacc..2a51678209 100644 --- a/doc/classes/AStar2D.xml +++ b/doc/classes/AStar2D.xml @@ -43,7 +43,8 @@ <argument index="2" name="weight_scale" type="float" default="1.0"> </argument> <description> - Adds a new point at the given position with the given identifier. The algorithm prefers points with lower [code]weight_scale[/code] to form a path. The [code]id[/code] must be 0 or larger, and the [code]weight_scale[/code] must be 1 or larger. + Adds a new point at the given position with the given identifier. The [code]id[/code] must be 0 or larger, and the [code]weight_scale[/code] must be 1 or larger. + The [code]weight_scale[/code] is multiplied by the result of [method _compute_cost] when determining the overall cost of traveling across a segment from a neighboring point to this point. Thus, all else being equal, the algorithm prefers points with lower [code]weight_scale[/code]s to form a path. [codeblocks] [gdscript] var astar = AStar2D.new() @@ -350,7 +351,7 @@ <argument index="1" name="weight_scale" type="float"> </argument> <description> - Sets the [code]weight_scale[/code] for the point with the given [code]id[/code]. + Sets the [code]weight_scale[/code] for the point with the given [code]id[/code]. The [code]weight_scale[/code] is multiplied by the result of [method _compute_cost] when determining the overall cost of traveling across a segment from a neighboring point to this point. </description> </method> </methods> diff --git a/doc/classes/Animation.xml b/doc/classes/Animation.xml index 3e33a879b3..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"> @@ -409,7 +409,7 @@ <argument index="1" name="key_idx" type="int"> </argument> <description> - Returns the transition curve (easing) for a specific key (see the built-in math function [method @GDScript.ease]). + Returns the transition curve (easing) for a specific key (see the built-in math function [method @GlobalScope.ease]). </description> </method> <method name="track_get_key_value" qualifiers="const"> @@ -592,7 +592,7 @@ <argument index="2" name="transition" type="float"> </argument> <description> - Sets the transition curve (easing) for a specific key (see the built-in math function [method @GDScript.ease]). + Sets the transition curve (easing) for a specific key (see the built-in math function [method @GlobalScope.ease]). </description> </method> <method name="track_set_key_value"> diff --git a/doc/classes/AnimationNodeStateMachinePlayback.xml b/doc/classes/AnimationNodeStateMachinePlayback.xml index 4dc88ffa56..c8468f9c8f 100644 --- a/doc/classes/AnimationNodeStateMachinePlayback.xml +++ b/doc/classes/AnimationNodeStateMachinePlayback.xml @@ -21,18 +21,17 @@ <link title="AnimationTree">https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link> </tutorials> <methods> - <method name="get_current_node" qualifiers="const"> - <return type="StringName"> + <method name="get_current_length" qualifiers="const"> + <return type="float"> </return> <description> - Returns the currently playing animation state. </description> </method> - <method name="get_travel_path" qualifiers="const"> - <return type="PackedStringArray"> + <method name="get_current_node" qualifiers="const"> + <return type="StringName"> </return> <description> - Returns the current travel path as computed internally by the A* algorithm. + Returns the currently playing animation state. </description> </method> <method name="get_current_play_position" qualifiers="const"> @@ -42,6 +41,13 @@ Returns the playback position within the current animation state. </description> </method> + <method name="get_travel_path" qualifiers="const"> + <return type="PackedStringArray"> + </return> + <description> + Returns the current travel path as computed internally by the A* algorithm. + </description> + </method> <method name="is_playing" qualifiers="const"> <return type="bool"> </return> diff --git a/doc/classes/Area2D.xml b/doc/classes/Area2D.xml index 72c40478bb..a02f077cf7 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,26 +176,30 @@ </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> <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> <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"> @@ -199,11 +209,14 @@ </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"> @@ -213,11 +226,14 @@ </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..bd43d619dd 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,26 +186,30 @@ </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> <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> <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"> @@ -209,11 +219,14 @@ </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"> @@ -223,11 +236,14 @@ </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 e4f9dcf993..cea5360234 100644 --- a/doc/classes/Array.xml +++ b/doc/classes/Array.xml @@ -191,11 +191,9 @@ </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. @@ -228,20 +226,15 @@ If [code]deep[/code] is [code]true[/code], a deep copy is performed: all nested arrays and dictionaries are duplicated and will not be shared with the original array. If [code]false[/code], a shallow copy is made and references to the original nested arrays and dictionaries are kept, so that modifying a sub-array or dictionary in the copy will also impact those referenced in the source array. </description> </method> - <method name="is_empty"> - <return type="bool"> - </return> - <description> - Returns [code]true[/code] if the array is empty. - </description> - </method> <method name="erase"> <return type="void"> </return> <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"> @@ -318,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"> @@ -330,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"> @@ -339,6 +335,13 @@ Reverses the order of the elements in the array. </description> </method> + <method name="is_empty"> + <return type="bool"> + </return> + <description> + Returns [code]true[/code] if the array is empty. + </description> + </method> <method name="max"> <return type="Variant"> </return> @@ -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"> @@ -482,7 +489,7 @@ <return type="void"> </return> <description> - Shuffles the array such that the items will have a random order. This method uses the global random number generator common to methods such as [method @GDScript.randi]. Call [method @GDScript.randomize] to ensure that a new seed will be used each time if you want non-reproducible shuffling. + Shuffles the array such that the items will have a random order. This method uses the global random number generator common to methods such as [method @GlobalScope.randi]. Call [method @GlobalScope.randomize] to ensure that a new seed will be used each time if you want non-reproducible shuffling. </description> </method> <method name="size"> @@ -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 59502e7017..e2c4ed1430 100644 --- a/doc/classes/ArrayMesh.xml +++ b/doc/classes/ArrayMesh.xml @@ -209,19 +209,15 @@ </method> </methods> <members> - <member name="blend_shape_mode" type="int" setter="set_blend_shape_mode" getter="get_blend_shape_mode" enum="ArrayMesh.BlendShapeMode" default="1"> - Sets the blend shape mode to one of [enum ArrayMesh.BlendShapeMode]. + <member name="blend_shape_mode" type="int" setter="set_blend_shape_mode" getter="get_blend_shape_mode" enum="Mesh.BlendShapeMode" default="1"> + Sets the blend shape mode to one of [enum Mesh.BlendShapeMode]. </member> <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> - <constant name="BLEND_SHAPE_MODE_NORMALIZED" value="0" enum="BlendShapeMode"> - Blend shapes are normalized. - </constant> - <constant name="BLEND_SHAPE_MODE_RELATIVE" value="1" enum="BlendShapeMode"> - Blend shapes are relative to base weight. - </constant> </constants> </class> 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/Button.xml b/doc/classes/Button.xml index e47198a381..8908c5f830 100644 --- a/doc/classes/Button.xml +++ b/doc/classes/Button.xml @@ -118,17 +118,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 )"> + Text outline [Color] 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,6 +142,21 @@ <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> diff --git a/doc/classes/Camera2D.xml b/doc/classes/Camera2D.xml index f17c56fb11..2a4e726d43 100644 --- a/doc/classes/Camera2D.xml +++ b/doc/classes/Camera2D.xml @@ -52,7 +52,7 @@ <method name="get_drag_margin" qualifiers="const"> <return type="float"> </return> - <argument index="0" name="side" type="int" enum="Side"> + <argument index="0" name="margin" type="int" enum="Side"> </argument> <description> Returns the specified [enum Side]'s margin. See also [member drag_bottom_margin], [member drag_top_margin], [member drag_left_margin], and [member drag_right_margin]. @@ -61,7 +61,7 @@ <method name="get_limit" qualifiers="const"> <return type="int"> </return> - <argument index="0" name="side" type="int" enum="Side"> + <argument index="0" name="margin" type="int" enum="Side"> </argument> <description> Returns the camera limit for the specified [enum Side]. See also [member limit_bottom], [member limit_top], [member limit_left], and [member limit_right]. @@ -85,7 +85,7 @@ <method name="set_drag_margin"> <return type="void"> </return> - <argument index="0" name="side" type="int" enum="Side"> + <argument index="0" name="margin" type="int" enum="Side"> </argument> <argument index="1" name="drag_margin" type="float"> </argument> @@ -96,7 +96,7 @@ <method name="set_limit"> <return type="void"> </return> - <argument index="0" name="side" type="int" enum="Side"> + <argument index="0" name="margin" type="int" enum="Side"> </argument> <argument index="1" name="limit" type="int"> </argument> @@ -118,10 +118,10 @@ <member name="drag_bottom_margin" type="float" setter="set_drag_margin" getter="get_drag_margin" default="0.2"> Bottom margin needed to drag the camera. A value of [code]1[/code] makes the camera move only when reaching the bottom edge of the screen. </member> - <member name="drag_horizontal_enabled" type="bool" setter="set_h_drag_enabled" getter="is_h_drag_enabled" default="false"> + <member name="drag_horizontal_enabled" type="bool" setter="set_drag_horizontal_enabled" getter="is_drag_horizontal_enabled" default="false"> If [code]true[/code], the camera only moves when reaching the horizontal (left and right) drag margins. If [code]false[/code], the camera moves horizontally regardless of margins. </member> - <member name="drag_horizontal_offset" type="float" setter="set_h_offset" getter="get_h_offset" default="0.0"> + <member name="drag_horizontal_offset" type="float" setter="set_drag_horizontal_offset" getter="get_drag_horizontal_offset" default="0.0"> The relative horizontal drag offset of the camera between the right ([code]-1[/code]) and left ([code]1[/code]) drag margins. [b]Note:[/b] Used to set the initial horizontal drag offset; determine the current offset; or force the current offset. It's not automatically updated when the horizontal drag margin is enabled or the drag margins are changed. </member> @@ -137,7 +137,7 @@ <member name="drag_vertical_enabled" type="bool" setter="set_drag_vertical_enabled" getter="is_drag_vertical_enabled" default="false"> If [code]true[/code], the camera only moves when reaching the vertical (top and bottom) drag margins. If [code]false[/code], the camera moves vertically regardless of the drag margins. </member> - <member name="drag_vertical_offset" type="float" setter="set_drag_verticaloffset" getter="get_drag_vertical_offset" default="0.0"> + <member name="drag_vertical_offset" type="float" setter="set_drag_vertical_offset" getter="get_drag_vertical_offset" default="0.0"> The relative vertical drag offset of the camera between the bottom ([code]-1[/code]) and top ([code]1[/code]) drag margins. [b]Note:[/b] Used to set the initial vertical drag offset; determine the current offset; or force the current offset. It's not automatically updated when the vertical drag margin is enabled or the drag margins are changed. </member> diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml index fcdd072c80..d13f431a16 100644 --- a/doc/classes/CanvasItem.xml +++ b/doc/classes/CanvasItem.xml @@ -9,7 +9,7 @@ Canvas items are drawn in tree order. By default, children are on top of their parents so a root [CanvasItem] will be drawn behind everything. This behavior can be changed on a per-item basis. A [CanvasItem] can also be hidden, which will also hide its children. It provides many ways to change parameters such as modulation (for itself and its children) and self modulation (only for itself), as well as its blend mode. Ultimately, a transform notification can be requested, which will notify the node that its global position changed in case the parent tree changed. - [b]Note:[/b] Unless otherwise specified, all methods that have angle parameters must have angles specified as [i]radians[/i]. To convert degrees to radians, use [method @GDScript.deg2rad]. + [b]Note:[/b] Unless otherwise specified, all methods that have angle parameters must have angles specified as [i]radians[/i]. To convert degrees to radians, use [method @GlobalScope.deg2rad]. </description> <tutorials> <link title="Viewport and canvas transforms">https://docs.godotengine.org/en/latest/tutorials/2d/2d_transforms.html</link> diff --git a/doc/classes/CheckBox.xml b/doc/classes/CheckBox.xml index 89fb960e88..bd91f9ed06 100644 --- a/doc/classes/CheckBox.xml +++ b/doc/classes/CheckBox.xml @@ -36,16 +36,16 @@ <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_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"> diff --git a/doc/classes/CheckButton.xml b/doc/classes/CheckButton.xml index 882f1c69f3..a05e532d4a 100644 --- a/doc/classes/CheckButton.xml +++ b/doc/classes/CheckButton.xml @@ -33,16 +33,16 @@ <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_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"> diff --git a/doc/classes/ClassDB.xml b/doc/classes/ClassDB.xml index 2a6a2ddd91..860bdc7c8f 100644 --- a/doc/classes/ClassDB.xml +++ b/doc/classes/ClassDB.xml @@ -67,6 +67,7 @@ </argument> <description> Returns an array with all the methods of [code]class[/code] or its ancestry if [code]no_inheritance[/code] is [code]false[/code]. Every element of the array is a [Dictionary] with the following keys: [code]args[/code], [code]default_args[/code], [code]flags[/code], [code]id[/code], [code]name[/code], [code]return: (class_name, hint, hint_string, name, type, usage)[/code]. + [b]Note:[/code] In exported release builds the debug info is not available, so the returned dictionaries will contain only method names. </description> </method> <method name="class_get_property" qualifiers="const"> diff --git a/doc/classes/CodeEdit.xml b/doc/classes/CodeEdit.xml index 8834ff82c6..f897f2405b 100644 --- a/doc/classes/CodeEdit.xml +++ b/doc/classes/CodeEdit.xml @@ -179,9 +179,9 @@ </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_readonly_color" type="Color" default="Color( 0.88, 0.88, 0.88, 0.5 )"> </theme_item> - <theme_item name="font_color_selected" type="Color" default="Color( 0, 0, 0, 1 )"> + <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. 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/Color.xml b/doc/classes/Color.xml index 755fd7eea2..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 [method @GDScript.ColorN] 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"> @@ -158,7 +178,7 @@ <argument index="0" name="to" type="Color"> </argument> <description> - Returns [code]true[/code] if this color and [code]color[/code] are approximately equal, by running [method @GDScript.is_equal_approx] on each component. + Returns [code]true[/code] if this color and [code]color[/code] are approximately equal, by running [method @GlobalScope.is_equal_approx] on each component. </description> </method> <method name="lerp"> diff --git a/doc/classes/ColorPickerButton.xml b/doc/classes/ColorPickerButton.xml index c04e8b9ea0..b351faf9ca 100644 --- a/doc/classes/ColorPickerButton.xml +++ b/doc/classes/ColorPickerButton.xml @@ -73,13 +73,13 @@ <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_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"> diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml index c3db716d3a..e5285587eb 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> @@ -213,17 +214,6 @@ Overrides the icon with given [code]name[/code] in the [member theme] resource the control uses. If [code]icon[/code] is [code]null[/code] or invalid, the override is cleared and the icon from assigned [Theme] is used. </description> </method> - <method name="add_theme_shader_override"> - <return type="void"> - </return> - <argument index="0" name="name" type="StringName"> - </argument> - <argument index="1" name="shader" type="Shader"> - </argument> - <description> - Overrides the [Shader] with given [code]name[/code] in the [member theme] resource the control uses. If [code]shader[/code] is [code]null[/code] or invalid, the override is cleared and the shader from assigned [Theme] is used. - </description> - </method> <method name="add_theme_stylebox_override"> <return type="void"> </return> @@ -317,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> @@ -417,20 +421,20 @@ Returns the position and size of the control relative to the top-left corner of the screen. See [member rect_position] and [member rect_size]. </description> </method> - <method name="get_offset" qualifiers="const"> - <return type="float"> + <method name="get_minimum_size" qualifiers="const"> + <return type="Vector2"> </return> - <argument index="0" name="side" type="int" enum="Side"> - </argument> <description> - Returns the anchor for the specified [enum Side]. A getter method for [member offset_bottom], [member offset_left], [member offset_right] and [member offset_top]. + Returns the minimum size for this control. See [member rect_min_size]. </description> </method> - <method name="get_minimum_size" qualifiers="const"> - <return type="Vector2"> + <method name="get_offset" qualifiers="const"> + <return type="float"> </return> + <argument index="0" name="offset" type="int" enum="Side"> + </argument> <description> - Returns the minimum size for this control. See [member rect_min_size]. + Returns the anchor for the specified [enum Side]. A getter method for [member offset_bottom], [member offset_left], [member offset_right] and [member offset_top]. </description> </method> <method name="get_parent_area_size" qualifiers="const"> @@ -685,15 +689,6 @@ Returns [code]true[/code] if icon with given [code]name[/code] has a valid override in this [Control] node. </description> </method> - <method name="has_theme_shader_override" qualifiers="const"> - <return type="bool"> - </return> - <argument index="0" name="name" type="StringName"> - </argument> - <description> - Returns [code]true[/code] if [Shader] with given [code]name[/code] has a valid override in this [Control] node. - </description> - </method> <method name="has_theme_stylebox" qualifiers="const"> <return type="bool"> </return> @@ -1063,6 +1058,13 @@ <member name="layout_direction" type="int" setter="set_layout_direction" getter="get_layout_direction" enum="Control.LayoutDirection" default="0"> Controls layout direction and text writing direction. Right-to-left layouts are necessary for certain languages (e.g. Arabic and Hebrew). </member> + <member name="mouse_default_cursor_shape" type="int" setter="set_default_cursor_shape" getter="get_default_cursor_shape" enum="Control.CursorShape" default="0"> + The default cursor shape for this control. Useful for Godot plugins and applications or games that use the system's mouse cursors. + [b]Note:[/b] On Linux, shapes may vary depending on the cursor theme of the system. + </member> + <member name="mouse_filter" type="int" setter="set_mouse_filter" getter="get_mouse_filter" enum="Control.MouseFilter" default="0"> + Controls whether the control will be able to receive mouse button input events through [method _gui_input] and how these events should be handled. Also controls whether the control can receive the [signal mouse_entered], and [signal mouse_exited] signals. See the constants to learn what each does. + </member> <member name="offset_bottom" type="float" setter="set_offset" getter="get_offset" default="0.0"> Distance between the node's bottom edge and its parent control, based on [member anchor_bottom]. Offsets are often controlled by one or multiple parent [Container] nodes, so you should not modify them manually if your node is a direct child of a [Container]. Offsets update automatically when you move or resize the node. @@ -1079,13 +1081,6 @@ Distance between the node's top edge and its parent control, based on [member anchor_top]. Offsets are often controlled by one or multiple parent [Container] nodes, so you should not modify them manually if your node is a direct child of a [Container]. Offsets update automatically when you move or resize the node. </member> - <member name="mouse_default_cursor_shape" type="int" setter="set_default_cursor_shape" getter="get_default_cursor_shape" enum="Control.CursorShape" default="0"> - The default cursor shape for this control. Useful for Godot plugins and applications or games that use the system's mouse cursors. - [b]Note:[/b] On Linux, shapes may vary depending on the cursor theme of the system. - </member> - <member name="mouse_filter" type="int" setter="set_mouse_filter" getter="get_mouse_filter" enum="Control.MouseFilter" default="0"> - Controls whether the control will be able to receive mouse button input events through [method _gui_input] and how these events should be handled. Also controls whether the control can receive the [signal mouse_entered], and [signal mouse_exited] signals. See the constants to learn what each does. - </member> <member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" default="false"> Enables whether rendering of [CanvasItem] based children should be clipped to this control's rectangle. If [code]true[/code], parts of a child which would be visibly outside of this control's rectangle will not be rendered. </member> diff --git a/doc/classes/Dictionary.xml b/doc/classes/Dictionary.xml index 2ca705cec7..d3fcbc9f64 100644 --- a/doc/classes/Dictionary.xml +++ b/doc/classes/Dictionary.xml @@ -215,13 +215,6 @@ Creates a copy of the dictionary, and returns it. The [code]deep[/code] parameter causes inner dictionaries and arrays to be copied recursively, but does not apply to objects. </description> </method> - <method name="is_empty"> - <return type="bool"> - </return> - <description> - Returns [code]true[/code] if the dictionary is empty. - </description> - </method> <method name="erase"> <return type="bool"> </return> @@ -299,6 +292,13 @@ [b]Note:[/b] Dictionaries with the same keys/values but in a different order will have a different hash. </description> </method> + <method name="is_empty"> + <return type="bool"> + </return> + <description> + Returns [code]true[/code] if the dictionary is empty. + </description> + </method> <method name="keys"> <return type="Array"> </return> diff --git a/doc/classes/EditorInterface.xml b/doc/classes/EditorInterface.xml index 5a61c05cee..b01af71852 100644 --- a/doc/classes/EditorInterface.xml +++ b/doc/classes/EditorInterface.xml @@ -40,13 +40,6 @@ Returns the edited (current) scene's root [Node]. </description> </method> - <method name="get_editor_settings"> - <return type="EditorSettings"> - </return> - <description> - Returns the editor's [EditorSettings] instance. - </description> - </method> <method name="get_editor_main_control"> <return type="Control"> </return> @@ -55,6 +48,13 @@ [b]Note:[/b] This returns the main editor control containing the whole editor, not the 2D or 3D viewports specifically. </description> </method> + <method name="get_editor_settings"> + <return type="EditorSettings"> + </return> + <description> + Returns the editor's [EditorSettings] instance. + </description> + </method> <method name="get_file_system_dock"> <return type="FileSystemDock"> </return> diff --git a/doc/classes/EditorSceneImporterAssimp.xml b/doc/classes/EditorSceneImporterAssimp.xml deleted file mode 100644 index c72d4ee25a..0000000000 --- a/doc/classes/EditorSceneImporterAssimp.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="EditorSceneImporterAssimp" inherits="EditorSceneImporter" version="4.0"> - <brief_description> - FBX 3D asset importer based on [url=http://assimp.org/]Assimp[/url]. - </brief_description> - <description> - This is an FBX 3D asset importer based on [url=http://assimp.org/]Assimp[/url]. It currently has many known limitations and works best with static meshes. Most animated meshes won't import correctly. - If exporting a FBX scene from Autodesk Maya, use these FBX export settings: - [codeblock] - - Smoothing Groups - - Smooth Mesh - - Triangluate (for meshes with blend shapes) - - Bake Animation - - Resample All - - Deformed Models - - Skins - - Blend Shapes - - Curve Filters - - Constant Key Reducer - - Auto Tangents Only - - *Do not check* Constraints (as it will break the file) - - Can check Embed Media (embeds textures into the exported FBX file) - - Note that when importing embedded media, the texture and mesh will be a single immutable file. - - You will have to re-export then re-import the FBX if the texture has changed. - - Units: Centimeters - - Up Axis: Y - - Binary format in FBX 2017 - [/codeblock] - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/EditorSceneImporterGLTF.xml b/doc/classes/EditorSceneImporterGLTF.xml new file mode 100644 index 0000000000..e717b30f73 --- /dev/null +++ b/doc/classes/EditorSceneImporterGLTF.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="EditorSceneImporterGLTF" inherits="EditorSceneImporter" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/doc/classes/EditorSceneImporterMesh.xml b/doc/classes/EditorSceneImporterMesh.xml new file mode 100644 index 0000000000..1c903bd889 --- /dev/null +++ b/doc/classes/EditorSceneImporterMesh.xml @@ -0,0 +1,160 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="EditorSceneImporterMesh" inherits="Resource" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + <method name="add_blend_shape"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + </description> + </method> + <method name="add_surface"> + <return type="void"> + </return> + <argument index="0" name="primitive" type="int" enum="Mesh.PrimitiveType"> + </argument> + <argument index="1" name="arrays" type="Array"> + </argument> + <argument index="2" name="blend_shapes" type="Array" default="[ ]"> + </argument> + <argument index="3" name="lods" type="Dictionary" default="{ +}"> + </argument> + <argument index="4" name="material" type="Material" default="null"> + </argument> + <argument index="5" name="arg5" type="String" default=""""> + </argument> + <description> + </description> + </method> + <method name="clear"> + <return type="void"> + </return> + <description> + </description> + </method> + <method name="get_blend_shape_count" qualifiers="const"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="get_blend_shape_mode" qualifiers="const"> + <return type="int" enum="Mesh.BlendShapeMode"> + </return> + <description> + </description> + </method> + <method name="get_blend_shape_name" qualifiers="const"> + <return type="String"> + </return> + <argument index="0" name="blend_shape_idx" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_mesh"> + <return type="ArrayMesh"> + </return> + <description> + </description> + </method> + <method name="get_surface_arrays" qualifiers="const"> + <return type="Array"> + </return> + <argument index="0" name="surface_idx" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_surface_blend_shape_arrays" qualifiers="const"> + <return type="Array"> + </return> + <argument index="0" name="surface_idx" type="int"> + </argument> + <argument index="1" name="blend_shape_idx" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_surface_count" qualifiers="const"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="get_surface_lod_count" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="surface_idx" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_surface_lod_indices" qualifiers="const"> + <return type="PackedInt32Array"> + </return> + <argument index="0" name="surface_idx" type="int"> + </argument> + <argument index="1" name="lod_idx" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_surface_lod_size" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="surface_idx" type="int"> + </argument> + <argument index="1" name="lod_idx" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_surface_material" qualifiers="const"> + <return type="Material"> + </return> + <argument index="0" name="surface_idx" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_surface_name" qualifiers="const"> + <return type="String"> + </return> + <argument index="0" name="surface_idx" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_surface_primitive_type"> + <return type="int" enum="Mesh.PrimitiveType"> + </return> + <argument index="0" name="surface_idx" type="int"> + </argument> + <description> + </description> + </method> + <method name="set_blend_shape_mode"> + <return type="void"> + </return> + <argument index="0" name="mode" type="int" enum="Mesh.BlendShapeMode"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="_data" type="Dictionary" setter="_set_data" getter="_get_data" default="{"surfaces": [ ]}"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/EditorSceneImporterMeshNode3D.xml b/doc/classes/EditorSceneImporterMeshNode3D.xml new file mode 100644 index 0000000000..1e459c1cee --- /dev/null +++ b/doc/classes/EditorSceneImporterMeshNode3D.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="EditorSceneImporterMeshNode3D" inherits="Node3D" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="mesh" type="EditorSceneImporterMesh" setter="set_mesh" getter="get_mesh"> + </member> + <member name="skeleton_path" type="NodePath" setter="set_skeleton_path" getter="get_skeleton_path" default="NodePath("")"> + </member> + <member name="skin" type="Skin" setter="set_skin" getter="get_skin"> + </member> + </members> + <constants> + </constants> +</class> 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/EncodedObjectAsID.xml b/doc/classes/EncodedObjectAsID.xml index fc68b47645..1e4fde453b 100644 --- a/doc/classes/EncodedObjectAsID.xml +++ b/doc/classes/EncodedObjectAsID.xml @@ -4,7 +4,7 @@ Holds a reference to an [Object]'s instance ID. </brief_description> <description> - Utility class which holds a reference to the internal identifier of an [Object] instance, as given by [method Object.get_instance_id]. This ID can then be used to retrieve the object instance with [method @GDScript.instance_from_id]. + Utility class which holds a reference to the internal identifier of an [Object] instance, as given by [method Object.get_instance_id]. This ID can then be used to retrieve the object instance with [method @GlobalScope.instance_from_id]. This class is used internally by the editor inspector and script debugger, but can also be used in plugins to pass and display objects as their IDs. </description> <tutorials> @@ -13,7 +13,7 @@ </methods> <members> <member name="object_id" type="int" setter="set_object_id" getter="get_object_id" default="0"> - The [Object] identifier stored in this [EncodedObjectAsID] instance. The object instance can be retrieved with [method @GDScript.instance_from_id]. + The [Object] identifier stored in this [EncodedObjectAsID] instance. The object instance can be retrieved with [method @GlobalScope.instance_from_id]. </member> </members> <constants> diff --git a/doc/classes/Engine.xml b/doc/classes/Engine.xml index c079085fb3..02b81ee9b7 100644 --- a/doc/classes/Engine.xml +++ b/doc/classes/Engine.xml @@ -51,13 +51,6 @@ Returns the frames per second of the running game. </description> </method> - <method name="get_process_frames" qualifiers="const"> - <return type="int"> - </return> - <description> - Returns the total number of frames passed since engine initialization which is advanced on each [b]process frame[/b], regardless of whether the render loop is enabled. See also [method get_frames_drawn]. - </description> - </method> <method name="get_license_info" qualifiers="const"> <return type="Dictionary"> </return> @@ -93,6 +86,13 @@ Returns the fraction through the current physics tick we are at the time of rendering the frame. This can be used to implement fixed timestep interpolation. </description> </method> + <method name="get_process_frames" qualifiers="const"> + <return type="int"> + </return> + <description> + Returns the total number of frames passed since engine initialization which is advanced on each [b]process frame[/b], regardless of whether the render loop is enabled. See also [method get_frames_drawn]. + </description> + </method> <method name="get_singleton" qualifiers="const"> <return type="Object"> </return> diff --git a/doc/classes/Environment.xml b/doc/classes/Environment.xml index 9dd4ecc37b..a986ec35c6 100644 --- a/doc/classes/Environment.xml +++ b/doc/classes/Environment.xml @@ -265,7 +265,9 @@ </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> diff --git a/doc/classes/File.xml b/doc/classes/File.xml index 2f7ac551cf..ff03f44789 100644 --- a/doc/classes/File.xml +++ b/doc/classes/File.xml @@ -481,8 +481,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/GLTFAccessor.xml b/doc/classes/GLTFAccessor.xml new file mode 100644 index 0000000000..a1f596f7dd --- /dev/null +++ b/doc/classes/GLTFAccessor.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="GLTFAccessor" inherits="Resource" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="buffer_view" type="int" setter="set_buffer_view" getter="get_buffer_view" default="0"> + </member> + <member name="byte_offset" type="int" setter="set_byte_offset" getter="get_byte_offset" default="0"> + </member> + <member name="component_type" type="int" setter="set_component_type" getter="get_component_type" default="0"> + </member> + <member name="count" type="int" setter="set_count" getter="get_count" default="0"> + </member> + <member name="max" type="PackedFloat64Array" setter="set_max" getter="get_max" default="PackedFloat64Array( )"> + </member> + <member name="min" type="PackedFloat64Array" setter="set_min" getter="get_min" default="PackedFloat64Array( )"> + </member> + <member name="normalized" type="bool" setter="set_normalized" getter="get_normalized" default="false"> + </member> + <member name="sparse_count" type="int" setter="set_sparse_count" getter="get_sparse_count" default="0"> + </member> + <member name="sparse_indices_buffer_view" type="int" setter="set_sparse_indices_buffer_view" getter="get_sparse_indices_buffer_view" default="0"> + </member> + <member name="sparse_indices_byte_offset" type="int" setter="set_sparse_indices_byte_offset" getter="get_sparse_indices_byte_offset" default="0"> + </member> + <member name="sparse_indices_component_type" type="int" setter="set_sparse_indices_component_type" getter="get_sparse_indices_component_type" default="0"> + </member> + <member name="sparse_values_buffer_view" type="int" setter="set_sparse_values_buffer_view" getter="get_sparse_values_buffer_view" default="0"> + </member> + <member name="sparse_values_byte_offset" type="int" setter="set_sparse_values_byte_offset" getter="get_sparse_values_byte_offset" default="0"> + </member> + <member name="type" type="int" setter="set_type" getter="get_type" default="0"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/GLTFAnimation.xml b/doc/classes/GLTFAnimation.xml new file mode 100644 index 0000000000..5c1fa02f11 --- /dev/null +++ b/doc/classes/GLTFAnimation.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="GLTFAnimation" inherits="Resource" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="loop" type="bool" setter="set_loop" getter="get_loop" default="false"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/GLTFBufferView.xml b/doc/classes/GLTFBufferView.xml new file mode 100644 index 0000000000..edaad85e0a --- /dev/null +++ b/doc/classes/GLTFBufferView.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="GLTFBufferView" inherits="Resource" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="buffer" type="int" setter="set_buffer" getter="get_buffer" default="-1"> + </member> + <member name="byte_length" type="int" setter="set_byte_length" getter="get_byte_length" default="0"> + </member> + <member name="byte_offset" type="int" setter="set_byte_offset" getter="get_byte_offset" default="0"> + </member> + <member name="byte_stride" type="int" setter="set_byte_stride" getter="get_byte_stride" default="-1"> + </member> + <member name="indices" type="bool" setter="set_indices" getter="get_indices" default="false"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/GLTFCamera.xml b/doc/classes/GLTFCamera.xml new file mode 100644 index 0000000000..0b95f2c802 --- /dev/null +++ b/doc/classes/GLTFCamera.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="GLTFCamera" inherits="Resource" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="fov_size" type="float" setter="set_fov_size" getter="get_fov_size" default="75.0"> + </member> + <member name="perspective" type="bool" setter="set_perspective" getter="get_perspective" default="true"> + </member> + <member name="zfar" type="float" setter="set_zfar" getter="get_zfar" default="4000.0"> + </member> + <member name="znear" type="float" setter="set_znear" getter="get_znear" default="0.05"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/GLTFDocument.xml b/doc/classes/GLTFDocument.xml new file mode 100644 index 0000000000..04c40dd752 --- /dev/null +++ b/doc/classes/GLTFDocument.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="GLTFDocument" inherits="Resource" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/doc/classes/GLTFLight.xml b/doc/classes/GLTFLight.xml new file mode 100644 index 0000000000..bfeaf9a86e --- /dev/null +++ b/doc/classes/GLTFLight.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="GLTFLight" inherits="Resource" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="color" type="Color" setter="set_color" getter="get_color" default="Color( 0, 0, 0, 1 )"> + </member> + <member name="inner_cone_angle" type="float" setter="set_inner_cone_angle" getter="get_inner_cone_angle" default="0.0"> + </member> + <member name="intensity" type="float" setter="set_intensity" getter="get_intensity" default="0.0"> + </member> + <member name="outer_cone_angle" type="float" setter="set_outer_cone_angle" getter="get_outer_cone_angle" default="0.0"> + </member> + <member name="range" type="float" setter="set_range" getter="get_range" default="0.0"> + </member> + <member name="type" type="String" setter="set_type" getter="get_type" default=""""> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/GLTFMesh.xml b/doc/classes/GLTFMesh.xml new file mode 100644 index 0000000000..55f79d2c55 --- /dev/null +++ b/doc/classes/GLTFMesh.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="GLTFMesh" inherits="Resource" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="blend_weights" type="PackedFloat32Array" setter="set_blend_weights" getter="get_blend_weights" default="PackedFloat32Array( )"> + </member> + <member name="mesh" type="EditorSceneImporterMesh" setter="set_mesh" getter="get_mesh"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/GLTFNode.xml b/doc/classes/GLTFNode.xml new file mode 100644 index 0000000000..5b7d4fadec --- /dev/null +++ b/doc/classes/GLTFNode.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="GLTFNode" inherits="Resource" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="camera" type="int" setter="set_camera" getter="get_camera" default="-1"> + </member> + <member name="children" type="PackedInt32Array" setter="set_children" getter="get_children" default="PackedInt32Array( )"> + </member> + <member name="fake_joint_parent" type="int" setter="set_fake_joint_parent" getter="get_fake_joint_parent" default="-1"> + </member> + <member name="height" type="int" setter="set_height" getter="get_height" default="-1"> + </member> + <member name="joint" type="bool" setter="set_joint" getter="get_joint" default="false"> + </member> + <member name="light" type="int" setter="set_light" getter="get_light" default="-1"> + </member> + <member name="mesh" type="int" setter="set_mesh" getter="get_mesh" default="-1"> + </member> + <member name="parent" type="int" setter="set_parent" getter="get_parent" default="-1"> + </member> + <member name="rotation" type="Quat" setter="set_rotation" getter="get_rotation" default="Quat( 0, 0, 0, 1 )"> + </member> + <member name="scale" type="Vector3" setter="set_scale" getter="get_scale" default="Vector3( 1, 1, 1 )"> + </member> + <member name="skeleton" type="int" setter="set_skeleton" getter="get_skeleton" default="-1"> + </member> + <member name="skin" type="int" setter="set_skin" getter="get_skin" default="-1"> + </member> + <member name="translation" type="Vector3" setter="set_translation" getter="get_translation" default="Vector3( 0, 0, 0 )"> + </member> + <member name="xform" type="Transform" setter="set_xform" getter="get_xform" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/GLTFSkeleton.xml b/doc/classes/GLTFSkeleton.xml new file mode 100644 index 0000000000..e27c838648 --- /dev/null +++ b/doc/classes/GLTFSkeleton.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="GLTFSkeleton" inherits="Resource" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + <method name="get_bone_attachment"> + <return type="BoneAttachment3D"> + </return> + <argument index="0" name="arg0" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_bone_attachment_count"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="get_godot_bone_node"> + <return type="Dictionary"> + </return> + <description> + </description> + </method> + <method name="get_godot_skeleton"> + <return type="Skeleton3D"> + </return> + <description> + </description> + </method> + <method name="get_unique_names"> + <return type="Array"> + </return> + <description> + </description> + </method> + <method name="set_godot_bone_node"> + <return type="void"> + </return> + <argument index="0" name="godot_bone_node" type="Dictionary"> + </argument> + <description> + </description> + </method> + <method name="set_unique_names"> + <return type="void"> + </return> + <argument index="0" name="unique_names" type="Array"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="joints" type="PackedInt32Array" setter="set_joints" getter="get_joints" default="PackedInt32Array( )"> + </member> + <member name="roots" type="PackedInt32Array" setter="set_roots" getter="get_roots" default="PackedInt32Array( )"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/GLTFSkin.xml b/doc/classes/GLTFSkin.xml new file mode 100644 index 0000000000..5a80c7097a --- /dev/null +++ b/doc/classes/GLTFSkin.xml @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="GLTFSkin" inherits="Resource" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + <method name="get_inverse_binds"> + <return type="Array"> + </return> + <description> + </description> + </method> + <method name="get_joint_i_to_bone_i"> + <return type="Dictionary"> + </return> + <description> + </description> + </method> + <method name="get_joint_i_to_name"> + <return type="Dictionary"> + </return> + <description> + </description> + </method> + <method name="set_inverse_binds"> + <return type="void"> + </return> + <argument index="0" name="inverse_binds" type="Array"> + </argument> + <description> + </description> + </method> + <method name="set_joint_i_to_bone_i"> + <return type="void"> + </return> + <argument index="0" name="joint_i_to_bone_i" type="Dictionary"> + </argument> + <description> + </description> + </method> + <method name="set_joint_i_to_name"> + <return type="void"> + </return> + <argument index="0" name="joint_i_to_name" type="Dictionary"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="godot_skin" type="Skin" setter="set_godot_skin" getter="get_godot_skin"> + </member> + <member name="joints" type="PackedInt32Array" setter="set_joints" getter="get_joints" default="PackedInt32Array( )"> + </member> + <member name="joints_original" type="PackedInt32Array" setter="set_joints_original" getter="get_joints_original" default="PackedInt32Array( )"> + </member> + <member name="non_joints" type="PackedInt32Array" setter="set_non_joints" getter="get_non_joints" default="PackedInt32Array( )"> + </member> + <member name="roots" type="PackedInt32Array" setter="set_roots" getter="get_roots" default="PackedInt32Array( )"> + </member> + <member name="skeleton" type="int" setter="set_skeleton" getter="get_skeleton" default="-1"> + </member> + <member name="skin_root" type="int" setter="set_skin_root" getter="get_skin_root" default="-1"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/GLTFSpecGloss.xml b/doc/classes/GLTFSpecGloss.xml new file mode 100644 index 0000000000..68cc7c845d --- /dev/null +++ b/doc/classes/GLTFSpecGloss.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="GLTFSpecGloss" inherits="Resource" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="diffuse_factor" type="Color" setter="set_diffuse_factor" getter="get_diffuse_factor" default="Color( 1, 1, 1, 1 )"> + </member> + <member name="diffuse_img" type="Image" setter="set_diffuse_img" getter="get_diffuse_img"> + </member> + <member name="gloss_factor" type="float" setter="set_gloss_factor" getter="get_gloss_factor" default="1.0"> + </member> + <member name="spec_gloss_img" type="Image" setter="set_spec_gloss_img" getter="get_spec_gloss_img"> + </member> + <member name="specular_factor" type="Color" setter="set_specular_factor" getter="get_specular_factor" default="Color( 1, 1, 1, 1 )"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/GLTFState.xml b/doc/classes/GLTFState.xml new file mode 100644 index 0000000000..f7763efdb1 --- /dev/null +++ b/doc/classes/GLTFState.xml @@ -0,0 +1,251 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="GLTFState" inherits="Resource" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + <method name="get_accessors"> + <return type="Array"> + </return> + <description> + </description> + </method> + <method name="get_animation_player"> + <return type="AnimationPlayer"> + </return> + <argument index="0" name="arg0" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_animation_players_count"> + <return type="int"> + </return> + <argument index="0" name="arg0" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_animations"> + <return type="Array"> + </return> + <description> + </description> + </method> + <method name="get_buffer_views"> + <return type="Array"> + </return> + <description> + </description> + </method> + <method name="get_cameras"> + <return type="Array"> + </return> + <description> + </description> + </method> + <method name="get_images"> + <return type="Array"> + </return> + <description> + </description> + </method> + <method name="get_lights"> + <return type="Array"> + </return> + <description> + </description> + </method> + <method name="get_materials"> + <return type="Array"> + </return> + <description> + </description> + </method> + <method name="get_meshes"> + <return type="Array"> + </return> + <description> + </description> + </method> + <method name="get_nodes"> + <return type="Array"> + </return> + <description> + </description> + </method> + <method name="get_scene_node"> + <return type="Node"> + </return> + <argument index="0" name="arg0" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_skeleton_to_node"> + <return type="Dictionary"> + </return> + <description> + </description> + </method> + <method name="get_skeletons"> + <return type="Array"> + </return> + <description> + </description> + </method> + <method name="get_skins"> + <return type="Array"> + </return> + <description> + </description> + </method> + <method name="get_textures"> + <return type="Array"> + </return> + <description> + </description> + </method> + <method name="get_unique_names"> + <return type="Array"> + </return> + <description> + </description> + </method> + <method name="set_accessors"> + <return type="void"> + </return> + <argument index="0" name="accessors" type="Array"> + </argument> + <description> + </description> + </method> + <method name="set_animations"> + <return type="void"> + </return> + <argument index="0" name="animations" type="Array"> + </argument> + <description> + </description> + </method> + <method name="set_buffer_views"> + <return type="void"> + </return> + <argument index="0" name="buffer_views" type="Array"> + </argument> + <description> + </description> + </method> + <method name="set_cameras"> + <return type="void"> + </return> + <argument index="0" name="cameras" type="Array"> + </argument> + <description> + </description> + </method> + <method name="set_images"> + <return type="void"> + </return> + <argument index="0" name="images" type="Array"> + </argument> + <description> + </description> + </method> + <method name="set_lights"> + <return type="void"> + </return> + <argument index="0" name="lights" type="Array"> + </argument> + <description> + </description> + </method> + <method name="set_materials"> + <return type="void"> + </return> + <argument index="0" name="materials" type="Array"> + </argument> + <description> + </description> + </method> + <method name="set_meshes"> + <return type="void"> + </return> + <argument index="0" name="meshes" type="Array"> + </argument> + <description> + </description> + </method> + <method name="set_nodes"> + <return type="void"> + </return> + <argument index="0" name="nodes" type="Array"> + </argument> + <description> + </description> + </method> + <method name="set_skeleton_to_node"> + <return type="void"> + </return> + <argument index="0" name="skeleton_to_node" type="Dictionary"> + </argument> + <description> + </description> + </method> + <method name="set_skeletons"> + <return type="void"> + </return> + <argument index="0" name="skeletons" type="Array"> + </argument> + <description> + </description> + </method> + <method name="set_skins"> + <return type="void"> + </return> + <argument index="0" name="skins" type="Array"> + </argument> + <description> + </description> + </method> + <method name="set_textures"> + <return type="void"> + </return> + <argument index="0" name="textures" type="Array"> + </argument> + <description> + </description> + </method> + <method name="set_unique_names"> + <return type="void"> + </return> + <argument index="0" name="unique_names" type="Array"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="buffers" type="Array" setter="set_buffers" getter="get_buffers" default="[ ]"> + </member> + <member name="glb_data" type="PackedByteArray" setter="set_glb_data" getter="get_glb_data" default="PackedByteArray( )"> + </member> + <member name="json" type="Dictionary" setter="set_json" getter="get_json" default="{}"> + </member> + <member name="major_version" type="int" setter="set_major_version" getter="get_major_version" default="0"> + </member> + <member name="minor_version" type="int" setter="set_minor_version" getter="get_minor_version" default="0"> + </member> + <member name="root_nodes" type="Array" setter="set_root_nodes" getter="get_root_nodes" default="[ ]"> + </member> + <member name="scene_name" type="String" setter="set_scene_name" getter="get_scene_name" default=""""> + </member> + <member name="use_named_skin_binds" type="bool" setter="set_use_named_skin_binds" getter="get_use_named_skin_binds" default="false"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/GLTFTexture.xml b/doc/classes/GLTFTexture.xml new file mode 100644 index 0000000000..c7f94ab0da --- /dev/null +++ b/doc/classes/GLTFTexture.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="GLTFTexture" inherits="Resource" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="src_image" type="int" setter="set_src_image" getter="get_src_image" default="4"> + </member> + </members> + <constants> + </constants> +</class> 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/GeometryInstance3D.xml b/doc/classes/GeometryInstance3D.xml index cc85ce295b..631a30abab 100644 --- a/doc/classes/GeometryInstance3D.xml +++ b/doc/classes/GeometryInstance3D.xml @@ -48,6 +48,8 @@ </member> <member name="gi_mode" type="int" setter="set_gi_mode" getter="get_gi_mode" enum="GeometryInstance3D.GIMode" default="0"> </member> + <member name="lod_bias" type="float" setter="set_lod_bias" getter="get_lod_bias" default="1.0"> + </member> <member name="lod_max_distance" type="float" setter="set_lod_max_distance" getter="get_lod_max_distance" default="0.0"> The GeometryInstance3D's max LOD distance. [b]Note:[/b] This property currently has no effect. diff --git a/doc/classes/GraphEdit.xml b/doc/classes/GraphEdit.xml index 2347627c31..10afa4c339 100644 --- a/doc/classes/GraphEdit.xml +++ b/doc/classes/GraphEdit.xml @@ -281,17 +281,17 @@ Emitted at the end of a GraphNode movement. </description> </signal> - <signal name="node_selected"> + <signal name="node_deselected"> <argument index="0" name="node" type="Node"> </argument> <description> - Emitted when a GraphNode is selected. </description> </signal> - <signal name="node_deselected"> + <signal name="node_selected"> <argument index="0" name="node" type="Node"> </argument> <description> + Emitted when a GraphNode is selected. </description> </signal> <signal name="paste_nodes_request"> 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/ItemList.xml b/doc/classes/ItemList.xml index 8542cdaca4..abc327e8bb 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> @@ -52,6 +53,22 @@ Removes all OpenType features from the item's text. </description> </method> + <method name="deselect"> + <return type="void"> + </return> + <argument index="0" name="idx" type="int"> + </argument> + <description> + Ensures the item associated with the specified index is not selected. + </description> + </method> + <method name="deselect_all"> + <return type="void"> + </return> + <description> + Ensures there are no items selected. + </description> + </method> <method name="ensure_current_is_visible"> <return type="void"> </return> @@ -471,22 +488,6 @@ Sorts items in the list by their text. </description> </method> - <method name="deselect"> - <return type="void"> - </return> - <argument index="0" name="idx" type="int"> - </argument> - <description> - Ensures the item associated with the specified index is not selected. - </description> - </method> - <method name="deselect_all"> - <return type="void"> - </return> - <description> - Ensures there are no items selected. - </description> - </method> </methods> <members> <member name="allow_reselect" type="bool" setter="set_allow_reselect" getter="get_allow_reselect" default="false"> @@ -614,7 +615,7 @@ <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_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"> diff --git a/doc/classes/JSONParseResult.xml b/doc/classes/JSONParseResult.xml index 991ebcd7a0..bc94f74b07 100644 --- a/doc/classes/JSONParseResult.xml +++ b/doc/classes/JSONParseResult.xml @@ -21,7 +21,7 @@ The error message if the JSON source was not successfully parsed. See the [enum Error] constants. </member> <member name="result" type="Variant" setter="set_result" getter="get_result"> - A [Variant] containing the parsed JSON. Use [method @GDScript.typeof] or the [code]is[/code] keyword to check if it is what you expect. For example, if the JSON source starts with curly braces ([code]{}[/code]), a [Dictionary] will be returned. If the JSON source starts with brackets ([code][][/code]), an [Array] will be returned. + A [Variant] containing the parsed JSON. Use [method @GlobalScope.typeof] or the [code]is[/code] keyword to check if it is what you expect. For example, if the JSON source starts with curly braces ([code]{}[/code]), a [Dictionary] will be returned. If the JSON source starts with brackets ([code][][/code]), an [Array] will be returned. [b]Note:[/b] The JSON specification does not define integer or float types, but only a [i]number[/i] type. Therefore, parsing a JSON text will convert all numerical values to [float] types. [b]Note:[/b] JSON objects do not preserve key order like Godot dictionaries, thus, you should not rely on keys being in a certain order if a dictionary is constructed from JSON. In contrast, JSON arrays retain the order of their elements: [codeblocks] 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..61ecff52e3 100644 --- a/doc/classes/LineEdit.xml +++ b/doc/classes/LineEdit.xml @@ -380,15 +380,15 @@ <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 )"> + <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_color_uneditable" type="Color" default="Color( 0.88, 0.88, 0.88, 0.5 )"> - Font color when editing is disabled. - </theme_item> <theme_item name="font_size" type="int"> Font size of the [LineEdit]'s text. </theme_item> + <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_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> diff --git a/doc/classes/LinkButton.xml b/doc/classes/LinkButton.xml index 93384843de..0227870152 100644 --- a/doc/classes/LinkButton.xml +++ b/doc/classes/LinkButton.xml @@ -81,10 +81,10 @@ <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_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"> diff --git a/doc/classes/MainLoop.xml b/doc/classes/MainLoop.xml index 7682379b64..537ecf2b2b 100644 --- a/doc/classes/MainLoop.xml +++ b/doc/classes/MainLoop.xml @@ -19,7 +19,7 @@ print("Initialized:") print(" Starting time: %s" % str(time_elapsed)) - func _idle(delta): + func _process(delta): time_elapsed += delta # Return true to end the main loop. return quit @@ -51,30 +51,30 @@ Called before the program exits. </description> </method> - <method name="_idle" qualifiers="virtual"> - <return type="bool"> + <method name="_initialize" qualifiers="virtual"> + <return type="void"> </return> - <argument index="0" name="delta" type="float"> - </argument> <description> - Called each idle frame with the time since the last idle frame as argument (in seconds). Equivalent to [method Node._process]. - If implemented, the method must return a boolean value. [code]true[/code] ends the main loop, while [code]false[/code] lets it proceed to the next frame. + Called once during initialization. </description> </method> - <method name="_initialize" qualifiers="virtual"> - <return type="void"> + <method name="_physics_process" qualifiers="virtual"> + <return type="bool"> </return> + <argument index="0" name="delta" type="float"> + </argument> <description> - Called once during initialization. + Called each physics frame with the time since the last physics frame as argument ([code]delta[/code], in seconds). Equivalent to [method Node._physics_process]. + If implemented, the method must return a boolean value. [code]true[/code] ends the main loop, while [code]false[/code] lets it proceed to the next frame. </description> </method> - <method name="_iteration" qualifiers="virtual"> + <method name="_process" qualifiers="virtual"> <return type="bool"> </return> <argument index="0" name="delta" type="float"> </argument> <description> - Called each physics frame with the time since the last physics frame as argument (in seconds). Equivalent to [method Node._physics_process]. + Called each process (idle) frame with the time since the last process frame as argument (in seconds). Equivalent to [method Node._process]. If implemented, the method must return a boolean value. [code]true[/code] ends the main loop, while [code]false[/code] lets it proceed to the next frame. </description> </method> 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..1e8874fdc5 100644 --- a/doc/classes/MenuButton.xml +++ b/doc/classes/MenuButton.xml @@ -59,13 +59,13 @@ <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_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"> diff --git a/doc/classes/Mesh.xml b/doc/classes/Mesh.xml index dff4b4f7ab..ed7c39d4d9 100644 --- a/doc/classes/Mesh.xml +++ b/doc/classes/Mesh.xml @@ -242,5 +242,11 @@ </constant> <constant name="ARRAY_FLAG_USE_8_BONE_WEIGHTS" value="134217728" enum="ArrayFormat"> </constant> + <constant name="BLEND_SHAPE_MODE_NORMALIZED" value="0" enum="BlendShapeMode"> + Blend shapes are normalized. + </constant> + <constant name="BLEND_SHAPE_MODE_RELATIVE" value="1" enum="BlendShapeMode"> + Blend shapes are relative to base weight. + </constant> </constants> </class> 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/NinePatchRect.xml b/doc/classes/NinePatchRect.xml index f4b9d75e91..d6de0ef4cf 100644 --- a/doc/classes/NinePatchRect.xml +++ b/doc/classes/NinePatchRect.xml @@ -12,7 +12,7 @@ <method name="get_patch_margin" qualifiers="const"> <return type="int"> </return> - <argument index="0" name="side" type="int" enum="Side"> + <argument index="0" name="margin" type="int" enum="Side"> </argument> <description> Returns the size of the margin on the specified [enum Side]. @@ -21,7 +21,7 @@ <method name="set_patch_margin"> <return type="void"> </return> - <argument index="0" name="side" type="int" enum="Side"> + <argument index="0" name="margin" type="int" enum="Side"> </argument> <argument index="1" name="value" type="int"> </argument> diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index 62d88afa51..5f0d6462e2 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -9,7 +9,7 @@ [b]Scene tree:[/b] The [SceneTree] contains the active tree of nodes. When a node is added to the scene tree, it receives the [constant NOTIFICATION_ENTER_TREE] notification and its [method _enter_tree] callback is triggered. Child nodes are always added [i]after[/i] their parent node, i.e. the [method _enter_tree] callback of a parent node will be triggered before its child's. Once all nodes have been added in the scene tree, they receive the [constant NOTIFICATION_READY] notification and their respective [method _ready] callbacks are triggered. For groups of nodes, the [method _ready] callback is called in reverse order, starting with the children and moving up to the parent nodes. This means that when adding a node to the scene tree, the following order will be used for the callbacks: [method _enter_tree] of the parent, [method _enter_tree] of the children, [method _ready] of the children and finally [method _ready] of the parent (recursively for the entire scene tree). - [b]Processing:[/b] Nodes can override the "process" state, so that they receive a callback on each frame requesting them to process (do something). Normal processing (callback [method _process], toggled with [method set_process]) happens as fast as possible and is dependent on the frame rate, so the processing time [i]delta[/i] is passed as an argument. Physics processing (callback [method _physics_process], toggled with [method set_physics_process]) happens a fixed number of times per second (60 by default) and is useful for code related to the physics engine. + [b]Processing:[/b] Nodes can override the "process" state, so that they receive a callback on each frame requesting them to process (do something). Normal processing (callback [method _process], toggled with [method set_process]) happens as fast as possible and is dependent on the frame rate, so the processing time [i]delta[/i] (in seconds) is passed as an argument. Physics processing (callback [method _physics_process], toggled with [method set_physics_process]) happens a fixed number of times per second (60 by default) and is useful for code related to the physics engine. Nodes can also process input events. When present, the [method _input] function will be called for each input that the program receives. In many cases, this can be overkill (unless used for simple projects), and the [method _unhandled_input] function might be preferred; it is called when the input event was not handled by anyone else (typically, GUI [Control] nodes), ensuring that the node only receives the events that were meant for it. To keep track of the scene hierarchy (especially when instancing scenes into other scenes), an "owner" can be set for the node with the [member owner] property. This keeps track of who instanced what. This is mostly useful when writing editors and tools, though. Finally, when a node is freed with [method Object.free] or [method queue_free], it will also free all its children. @@ -65,7 +65,7 @@ <argument index="0" name="delta" type="float"> </argument> <description> - Called during the physics processing step of the main loop. Physics processing means that the frame rate is synced to the physics, i.e. the [code]delta[/code] variable should be constant. + Called during the physics processing step of the main loop. Physics processing means that the frame rate is synced to the physics, i.e. the [code]delta[/code] variable should be constant. [code]delta[/code] is in seconds. It is only called if physics processing is enabled, which is done automatically if this method is overridden, and can be toggled with [method set_physics_process]. Corresponds to the [constant NOTIFICATION_PHYSICS_PROCESS] notification in [method Object._notification]. [b]Note:[/b] This method is only called if the node is present in the scene tree (i.e. if it's not orphan). @@ -77,7 +77,7 @@ <argument index="0" name="delta" type="float"> </argument> <description> - Called during the processing step of the main loop. Processing happens at every frame and as fast as possible, so the [code]delta[/code] time since the previous frame is not constant. + Called during the processing step of the main loop. Processing happens at every frame and as fast as possible, so the [code]delta[/code] time since the previous frame is not constant. [code]delta[/code] is in seconds. It is only called if processing is enabled, which is done automatically if this method is overridden, and can be toggled with [method set_process]. Corresponds to the [constant NOTIFICATION_PROCESS] notification in [method Object._notification]. [b]Note:[/b] This method is only called if the node is present in the scene tree (i.e. if it's not orphan). @@ -361,7 +361,7 @@ <return type="float"> </return> <description> - Returns the time elapsed since the last physics-bound frame (see [method _physics_process]). This is always a constant value in physics processing unless the frames per second is changed via [member Engine.iterations_per_second]. + Returns the time elapsed (in seconds) since the last physics-bound frame (see [method _physics_process]). This is always a constant value in physics processing unless the frames per second is changed via [member Engine.iterations_per_second]. </description> </method> <method name="get_process_delta_time" qualifiers="const"> @@ -590,7 +590,7 @@ <return type="void"> </return> <description> - Moves this node to the bottom of parent node's children hierarchy. This is often useful in GUIs ([Control] nodes), because their order of drawing depends on their order in the tree, i.e. the further they are on the node list, the higher they are drawn. After using [code]raise[/code], a Control will be drawn on top of their siblings. + Moves this node to the bottom of parent node's children hierarchy. This is often useful in GUIs ([Control] nodes), because their order of drawing depends on their order in the tree. The top Node is drawn first, then any siblings below the top Node in the hierarchy are successively drawn on top of it. After using [code]raise[/code], a Control will be drawn on top of its siblings. </description> </method> <method name="remove_and_skip"> @@ -623,10 +623,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"> diff --git a/doc/classes/Node3D.xml b/doc/classes/Node3D.xml index f6ff514474..8b56050058 100644 --- a/doc/classes/Node3D.xml +++ b/doc/classes/Node3D.xml @@ -6,7 +6,7 @@ <description> Most basic 3D game object, with a 3D [Transform] and visibility settings. All other 3D game objects inherit from Node3D. Use [Node3D] as a parent node to move, scale, rotate and show/hide children in a 3D project. Affine operations (rotate, scale, translate) happen in parent's local coordinate system, unless the [Node3D] object is set as top-level. Affine operations in this coordinate system correspond to direct affine operations on the [Node3D]'s transform. The word local below refers to this coordinate system. The coordinate system that is attached to the [Node3D] object itself is referred to as object-local coordinate system. - [b]Note:[/b] Unless otherwise specified, all methods that have angle parameters must have angles specified as [i]radians[/i]. To convert degrees to radians, use [method @GDScript.deg2rad]. + [b]Note:[/b] Unless otherwise specified, all methods that have angle parameters must have angles specified as [i]radians[/i]. To convert degrees to radians, use [method @GlobalScope.deg2rad]. </description> <tutorials> <link title="Introduction to 3D">https://docs.godotengine.org/en/latest/tutorials/3d/introduction_to_3d.html</link> @@ -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..8620de1378 100644 --- a/doc/classes/OS.xml +++ b/doc/classes/OS.xml @@ -25,6 +25,29 @@ [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> @@ -71,48 +94,34 @@ </argument> <argument index="1" name="arguments" type="PackedStringArray"> </argument> - <argument index="2" name="blocking" type="bool" default="true"> + <argument index="2" name="output" type="Array" default="[ ]"> </argument> - <argument index="3" 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. @@ -313,6 +322,14 @@ [b]Note:[/b] This method is implemented on Windows. </description> </method> + <method name="get_thread_caller_id" qualifiers="const"> + <return type="int"> + </return> + <description> + 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"> <return type="int"> </return> diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml index 6fc696b83c..f55b8597dd 100644 --- a/doc/classes/Object.xml +++ b/doc/classes/Object.xml @@ -394,7 +394,7 @@ </return> <description> Returns the object's unique instance ID. - This ID can be saved in [EncodedObjectAsID], and can be used to retrieve the object instance with [method @GDScript.instance_from_id]. + This ID can be saved in [EncodedObjectAsID], and can be used to retrieve the object instance with [method @GlobalScope.instance_from_id]. </description> </method> <method name="get_meta" qualifiers="const"> diff --git a/doc/classes/OptionButton.xml b/doc/classes/OptionButton.xml index 53309bae96..1a80962751 100644 --- a/doc/classes/OptionButton.xml +++ b/doc/classes/OptionButton.xml @@ -253,13 +253,13 @@ <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_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"> diff --git a/doc/classes/PackedByteArray.xml b/doc/classes/PackedByteArray.xml index b00c59ade9..75fb7c1465 100644 --- a/doc/classes/PackedByteArray.xml +++ b/doc/classes/PackedByteArray.xml @@ -92,13 +92,6 @@ Creates a copy of the array, and returns it. </description> </method> - <method name="is_empty"> - <return type="bool"> - </return> - <description> - Returns [code]true[/code] if the array is empty. - </description> - </method> <method name="get_string_from_ascii"> <return type="String"> </return> @@ -171,6 +164,13 @@ Reverses the order of the elements in the array. </description> </method> + <method name="is_empty"> + <return type="bool"> + </return> + <description> + Returns [code]true[/code] if the array is empty. + </description> + </method> <method name="operator !=" qualifiers="operator"> <return type="bool"> </return> diff --git a/doc/classes/PackedColorArray.xml b/doc/classes/PackedColorArray.xml index d6cd5196e4..48d5822f7c 100644 --- a/doc/classes/PackedColorArray.xml +++ b/doc/classes/PackedColorArray.xml @@ -59,13 +59,6 @@ Creates a copy of the array, and returns it. </description> </method> - <method name="is_empty"> - <return type="bool"> - </return> - <description> - Returns [code]true[/code] if the array is empty. - </description> - </method> <method name="has"> <return type="bool"> </return> @@ -93,6 +86,13 @@ Reverses the order of the elements in the array. </description> </method> + <method name="is_empty"> + <return type="bool"> + </return> + <description> + Returns [code]true[/code] if the array is empty. + </description> + </method> <method name="operator !=" qualifiers="operator"> <return type="bool"> </return> diff --git a/doc/classes/PackedFloat32Array.xml b/doc/classes/PackedFloat32Array.xml index 52f6ece158..6598828089 100644 --- a/doc/classes/PackedFloat32Array.xml +++ b/doc/classes/PackedFloat32Array.xml @@ -60,13 +60,6 @@ Creates a copy of the array, and returns it. </description> </method> - <method name="is_empty"> - <return type="bool"> - </return> - <description> - Returns [code]true[/code] if the array is empty. - </description> - </method> <method name="has"> <return type="bool"> </return> @@ -94,6 +87,13 @@ Reverses the order of the elements in the array. </description> </method> + <method name="is_empty"> + <return type="bool"> + </return> + <description> + Returns [code]true[/code] if the array is empty. + </description> + </method> <method name="operator !=" qualifiers="operator"> <return type="bool"> </return> diff --git a/doc/classes/PackedFloat64Array.xml b/doc/classes/PackedFloat64Array.xml index 2f317d4b8c..d116c6756b 100644 --- a/doc/classes/PackedFloat64Array.xml +++ b/doc/classes/PackedFloat64Array.xml @@ -60,13 +60,6 @@ Creates a copy of the array, and returns it. </description> </method> - <method name="is_empty"> - <return type="bool"> - </return> - <description> - Returns [code]true[/code] if the array is empty. - </description> - </method> <method name="has"> <return type="bool"> </return> @@ -94,6 +87,13 @@ Reverses the order of the elements in the array. </description> </method> + <method name="is_empty"> + <return type="bool"> + </return> + <description> + Returns [code]true[/code] if the array is empty. + </description> + </method> <method name="operator !=" qualifiers="operator"> <return type="bool"> </return> diff --git a/doc/classes/PackedInt32Array.xml b/doc/classes/PackedInt32Array.xml index bda902b15f..2ac7a67b4b 100644 --- a/doc/classes/PackedInt32Array.xml +++ b/doc/classes/PackedInt32Array.xml @@ -60,13 +60,6 @@ Creates a copy of the array, and returns it. </description> </method> - <method name="is_empty"> - <return type="bool"> - </return> - <description> - Returns [code]true[/code] if the array is empty. - </description> - </method> <method name="has"> <return type="bool"> </return> @@ -94,6 +87,13 @@ Reverses the order of the elements in the array. </description> </method> + <method name="is_empty"> + <return type="bool"> + </return> + <description> + Returns [code]true[/code] if the array is empty. + </description> + </method> <method name="operator !=" qualifiers="operator"> <return type="bool"> </return> diff --git a/doc/classes/PackedInt64Array.xml b/doc/classes/PackedInt64Array.xml index 9c52ec808b..a7b6bf0a0f 100644 --- a/doc/classes/PackedInt64Array.xml +++ b/doc/classes/PackedInt64Array.xml @@ -60,13 +60,6 @@ Creates a copy of the array, and returns it. </description> </method> - <method name="is_empty"> - <return type="bool"> - </return> - <description> - Returns [code]true[/code] if the array is empty. - </description> - </method> <method name="has"> <return type="bool"> </return> @@ -94,6 +87,13 @@ Reverses the order of the elements in the array. </description> </method> + <method name="is_empty"> + <return type="bool"> + </return> + <description> + Returns [code]true[/code] if the array is empty. + </description> + </method> <method name="operator !=" qualifiers="operator"> <return type="bool"> </return> diff --git a/doc/classes/PackedSceneGLTF.xml b/doc/classes/PackedSceneGLTF.xml new file mode 100644 index 0000000000..a04c6ef0b6 --- /dev/null +++ b/doc/classes/PackedSceneGLTF.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="PackedSceneGLTF" inherits="PackedScene" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + <method name="export_gltf"> + <return type="int" enum="Error"> + </return> + <argument index="0" name="node" type="Node"> + </argument> + <argument index="1" name="path" type="String"> + </argument> + <argument index="2" name="flags" type="int" default="0"> + </argument> + <argument index="3" name="bake_fps" type="float" default="1000.0"> + </argument> + <description> + </description> + </method> + <method name="import_gltf_scene"> + <return type="Node"> + </return> + <argument index="0" name="path" type="String"> + </argument> + <argument index="1" name="flags" type="int" default="0"> + </argument> + <argument index="2" name="bake_fps" type="float" default="1000.0"> + </argument> + <argument index="3" name="state" type="GLTFState" default="null"> + </argument> + <description> + </description> + </method> + <method name="pack_gltf"> + <return type="void"> + </return> + <argument index="0" name="path" type="String"> + </argument> + <argument index="1" name="flags" type="int" default="0"> + </argument> + <argument index="2" name="bake_fps" type="float" default="1000.0"> + </argument> + <argument index="3" name="state" type="GLTFState" default="null"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="_bundled" type="Dictionary" setter="_set_bundled_scene" getter="_get_bundled_scene" override="true" default="{"conn_count": 0,"conns": PackedInt32Array( ),"editable_instances": [ ],"names": PackedStringArray( ),"node_count": 0,"node_paths": [ ],"nodes": PackedInt32Array( ),"variants": [ ],"version": 2}" /> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/PackedStringArray.xml b/doc/classes/PackedStringArray.xml index 24406c53d4..fb7ed2a906 100644 --- a/doc/classes/PackedStringArray.xml +++ b/doc/classes/PackedStringArray.xml @@ -60,13 +60,6 @@ Creates a copy of the array, and returns it. </description> </method> - <method name="is_empty"> - <return type="bool"> - </return> - <description> - Returns [code]true[/code] if the array is empty. - </description> - </method> <method name="has"> <return type="bool"> </return> @@ -94,6 +87,13 @@ Reverses the order of the elements in the array. </description> </method> + <method name="is_empty"> + <return type="bool"> + </return> + <description> + Returns [code]true[/code] if the array is empty. + </description> + </method> <method name="operator !=" qualifiers="operator"> <return type="bool"> </return> diff --git a/doc/classes/PackedVector2Array.xml b/doc/classes/PackedVector2Array.xml index 2f583e2b9b..eb364ddb18 100644 --- a/doc/classes/PackedVector2Array.xml +++ b/doc/classes/PackedVector2Array.xml @@ -60,13 +60,6 @@ Creates a copy of the array, and returns it. </description> </method> - <method name="is_empty"> - <return type="bool"> - </return> - <description> - Returns [code]true[/code] if the array is empty. - </description> - </method> <method name="has"> <return type="bool"> </return> @@ -94,6 +87,13 @@ Reverses the order of the elements in the array. </description> </method> + <method name="is_empty"> + <return type="bool"> + </return> + <description> + Returns [code]true[/code] if the array is empty. + </description> + </method> <method name="operator !=" qualifiers="operator"> <return type="bool"> </return> diff --git a/doc/classes/PackedVector3Array.xml b/doc/classes/PackedVector3Array.xml index 6004454dc9..08ce187b5c 100644 --- a/doc/classes/PackedVector3Array.xml +++ b/doc/classes/PackedVector3Array.xml @@ -59,13 +59,6 @@ Creates a copy of the array, and returns it. </description> </method> - <method name="is_empty"> - <return type="bool"> - </return> - <description> - Returns [code]true[/code] if the array is empty. - </description> - </method> <method name="has"> <return type="bool"> </return> @@ -93,6 +86,13 @@ Reverses the order of the elements in the array. </description> </method> + <method name="is_empty"> + <return type="bool"> + </return> + <description> + Returns [code]true[/code] if the array is empty. + </description> + </method> <method name="operator !=" qualifiers="operator"> <return type="bool"> </return> 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/Plane.xml b/doc/classes/Plane.xml index e3242512c4..ed96f753c2 100644 --- a/doc/classes/Plane.xml +++ b/doc/classes/Plane.xml @@ -142,7 +142,7 @@ <argument index="0" name="to_plane" type="Plane"> </argument> <description> - Returns [code]true[/code] if this plane and [code]plane[/code] are approximately equal, by running [method @GDScript.is_equal_approx] on each component. + Returns [code]true[/code] if this plane and [code]plane[/code] are approximately equal, by running [method @GlobalScope.is_equal_approx] on each component. </description> </method> <method name="is_point_over"> diff --git a/doc/classes/PopupMenu.xml b/doc/classes/PopupMenu.xml index 2532af9a0c..47e8e57a4e 100644 --- a/doc/classes/PopupMenu.xml +++ b/doc/classes/PopupMenu.xml @@ -717,19 +717,19 @@ <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_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"> diff --git a/doc/classes/ProgressBar.xml b/doc/classes/ProgressBar.xml index c05cbf4413..bb7fd31ee8 100644 --- a/doc/classes/ProgressBar.xml +++ b/doc/classes/ProgressBar.xml @@ -32,7 +32,7 @@ <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_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"> diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index d623b0432f..be72f83406 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -1052,12 +1052,16 @@ 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/cluster_builder/max_clustered_elements" type="float" setter="" getter="" default="512"> + </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> <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> + <member name="rendering/forward_renderer/threaded_render_minimum_instances" type="int" setter="" getter="" default="500"> + </member> <member name="rendering/gpu_lightmapper/performance/max_rays_per_pass" type="int" setter="" getter="" default="32"> </member> <member name="rendering/gpu_lightmapper/performance/max_rays_per_probe_pass" type="int" setter="" getter="" default="64"> @@ -1084,9 +1088,6 @@ </member> <member name="rendering/lightmapper/probe_capture_update_speed" type="float" setter="" getter="" default="15"> </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> <member name="rendering/limits/time/time_rollover_secs" type="float" setter="" getter="" default="3600"> </member> <member name="rendering/quality/2d/snap_2d_transforms_to_pixel" type="bool" setter="" getter="" default="false"> @@ -1114,6 +1115,8 @@ <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> + <member name="rendering/quality/directional_shadow/16_bits" type="bool" setter="" getter="" default="true"> + </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> @@ -1132,6 +1135,8 @@ [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/quality/gi/use_half_resolution" type="bool" setter="" getter="" default="false"> + </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> @@ -1153,6 +1158,12 @@ <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> + <member name="rendering/quality/mesh_lod/threshold_pixels" type="float" setter="" getter="" default="1.0"> + </member> + <member name="rendering/quality/rd_renderer/use_low_end_renderer" type="bool" setter="" getter="" default="false"> + </member> + <member name="rendering/quality/rd_renderer/use_low_end_renderer.mobile" type="bool" setter="" getter="" default="true"> + </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> @@ -1217,7 +1228,9 @@ <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> - <member name="rendering/quality/shadow_atlas/quadrant_0_subdiv" type="int" setter="" getter="" default="1"> + <member name="rendering/quality/shadow_atlas/16_bits" type="bool" setter="" getter="" default="true"> + </member> + <member name="rendering/quality/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/quality/shadow_atlas/quadrant_1_subdiv" type="int" setter="" getter="" default="2"> @@ -1277,18 +1290,20 @@ <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> - <member name="rendering/sdfgi/frames_to_converge" type="int" setter="" getter="" default="1"> + <member name="rendering/sdfgi/frames_to_converge" type="int" setter="" getter="" default="4"> </member> - <member name="rendering/sdfgi/probe_ray_count" type="int" setter="" getter="" default="2"> + <member name="rendering/sdfgi/frames_to_update_lights" type="int" setter="" getter="" default="2"> </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/sdfgi/probe_ray_count" type="int" setter="" getter="" default="1"> </member> - <member name="rendering/volumetric_fog/directional_shadow_shrink" type="int" setter="" getter="" default="512"> + <member name="rendering/spatial_indexer/threaded_cull_minimum_instances" type="int" setter="" getter="" default="1000"> </member> - <member name="rendering/volumetric_fog/positional_shadow_shrink" type="int" setter="" getter="" default="512"> + <member name="rendering/spatial_indexer/update_iterations_per_frame" type="int" setter="" getter="" default="10"> + </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> - <member name="rendering/volumetric_fog/use_filter" type="int" setter="" getter="" default="0"> + <member name="rendering/volumetric_fog/use_filter" type="int" setter="" getter="" default="1"> </member> <member name="rendering/volumetric_fog/volume_depth" type="int" setter="" getter="" default="128"> </member> diff --git a/doc/classes/Quat.xml b/doc/classes/Quat.xml index 425e82c744..ef83ae7fb9 100644 --- a/doc/classes/Quat.xml +++ b/doc/classes/Quat.xml @@ -127,7 +127,7 @@ <argument index="0" name="to" type="Quat"> </argument> <description> - Returns [code]true[/code] if this quaterion and [code]quat[/code] are approximately equal, by running [method @GDScript.is_equal_approx] on each component. + Returns [code]true[/code] if this quaterion and [code]quat[/code] are approximately equal, by running [method @GlobalScope.is_equal_approx] on each component. </description> </method> <method name="is_normalized"> diff --git a/doc/classes/Rect2.xml b/doc/classes/Rect2.xml index 3d2852f393..5d7ff39587 100644 --- a/doc/classes/Rect2.xml +++ b/doc/classes/Rect2.xml @@ -72,16 +72,6 @@ Returns a [Rect2] with equivalent position and area, modified so that the top-left corner is the origin and [code]width[/code] and [code]height[/code] are positive. </description> </method> - <method name="intersection"> - <return type="Rect2"> - </return> - <argument index="0" name="b" type="Rect2"> - </argument> - <description> - Returns the intersection of this [Rect2] and [code]b[/code]. - If the rectangles do not intersect, an empty [Rect2] is returned. - </description> - </method> <method name="encloses"> <return type="bool"> </return> @@ -134,7 +124,7 @@ <method name="grow_side"> <return type="Rect2"> </return> - <argument index="0" name="side" type="int" enum="Side"> + <argument index="0" name="side" type="int"> </argument> <argument index="1" name="amount" type="float"> </argument> @@ -158,6 +148,16 @@ Returns [code]true[/code] if the [Rect2] contains a point. </description> </method> + <method name="intersection"> + <return type="Rect2"> + </return> + <argument index="0" name="b" type="Rect2"> + </argument> + <description> + Returns the intersection of this [Rect2] and [code]b[/code]. + If the rectangles do not intersect, an empty [Rect2] is returned. + </description> + </method> <method name="intersects"> <return type="bool"> </return> diff --git a/doc/classes/Rect2i.xml b/doc/classes/Rect2i.xml index 66e5dae78a..e581ccdb11 100644 --- a/doc/classes/Rect2i.xml +++ b/doc/classes/Rect2i.xml @@ -70,16 +70,6 @@ Returns a [Rect2i] with equivalent position and area, modified so that the top-left corner is the origin and [code]width[/code] and [code]height[/code] are positive. </description> </method> - <method name="intersection"> - <return type="Rect2i"> - </return> - <argument index="0" name="b" type="Rect2i"> - </argument> - <description> - Returns the intersection of this [Rect2i] and [code]b[/code]. - If the rectangles do not intersect, an empty [Rect2i] is returned. - </description> - </method> <method name="encloses"> <return type="bool"> </return> @@ -132,7 +122,7 @@ <method name="grow_side"> <return type="Rect2i"> </return> - <argument index="0" name="side" type="int" enum="Side"> + <argument index="0" name="side" type="int"> </argument> <argument index="1" name="amount" type="int"> </argument> @@ -156,6 +146,16 @@ Returns [code]true[/code] if the [Rect2i] contains a point. </description> </method> + <method name="intersection"> + <return type="Rect2i"> + </return> + <argument index="0" name="b" type="Rect2i"> + </argument> + <description> + Returns the intersection of this [Rect2i] and [code]b[/code]. + If the rectangles do not intersect, an empty [Rect2i] is returned. + </description> + </method> <method name="intersects"> <return type="bool"> </return> 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/ReflectionProbe.xml b/doc/classes/ReflectionProbe.xml index 5458b496da..cd08778c89 100644 --- a/doc/classes/ReflectionProbe.xml +++ b/doc/classes/ReflectionProbe.xml @@ -37,6 +37,8 @@ <member name="interior" type="bool" setter="set_as_interior" getter="is_set_as_interior" default="false"> If [code]true[/code], reflections will ignore sky contribution. </member> + <member name="lod_threshold" type="float" setter="set_lod_threshold" getter="get_lod_threshold" default="1.0"> + </member> <member name="max_distance" type="float" setter="set_max_distance" getter="get_max_distance" default="0.0"> Sets the max distance away from the probe an object can be before it is culled. </member> diff --git a/doc/classes/RenderingDevice.xml b/doc/classes/RenderingDevice.xml index 7e5df9c40d..84e307b852 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> @@ -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> @@ -730,6 +820,8 @@ </argument> <argument index="1" name="data" type="PackedByteArray" default="PackedByteArray( )"> </argument> + <argument index="2" name="use_as_storage" type="bool" default="false"> + </argument> <description> </description> </method> @@ -743,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"> @@ -1505,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 036b50f0ed..efc751bb94 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -859,6 +859,12 @@ Tries to free an object in the RenderingServer. </description> </method> + <method name="get_frame_setup_time_cpu" qualifiers="const"> + <return type="float"> + </return> + <description> + </description> + </method> <method name="get_render_info"> <return type="int"> </return> @@ -1354,7 +1360,7 @@ <argument index="1" name="scenario" type="RID"> </argument> <description> - Returns an array of object IDs intersecting with the provided AABB. Only visual 3D nodes are considered, such as [MeshInstance3D] or [DirectionalLight3D]. Use [method @GDScript.instance_from_id] to obtain the actual nodes. A scenario RID must be provided, which is available in the [World3D] you want to query. This forces an update for all resources queued to update. + Returns an array of object IDs intersecting with the provided AABB. Only visual 3D nodes are considered, such as [MeshInstance3D] or [DirectionalLight3D]. Use [method @GlobalScope.instance_from_id] to obtain the actual nodes. A scenario RID must be provided, which is available in the [World3D] you want to query. This forces an update for all resources queued to update. [b]Warning:[/b] This function is primarily intended for editor usage. For in-game use cases, prefer physics collision. </description> </method> @@ -1366,7 +1372,7 @@ <argument index="1" name="scenario" type="RID"> </argument> <description> - Returns an array of object IDs intersecting with the provided convex shape. Only visual 3D nodes are considered, such as [MeshInstance3D] or [DirectionalLight3D]. Use [method @GDScript.instance_from_id] to obtain the actual nodes. A scenario RID must be provided, which is available in the [World3D] you want to query. This forces an update for all resources queued to update. + Returns an array of object IDs intersecting with the provided convex shape. Only visual 3D nodes are considered, such as [MeshInstance3D] or [DirectionalLight3D]. Use [method @GlobalScope.instance_from_id] to obtain the actual nodes. A scenario RID must be provided, which is available in the [World3D] you want to query. This forces an update for all resources queued to update. [b]Warning:[/b] This function is primarily intended for editor usage. For in-game use cases, prefer physics collision. </description> </method> @@ -1380,7 +1386,7 @@ <argument index="2" name="scenario" type="RID"> </argument> <description> - Returns an array of object IDs intersecting with the provided 3D ray. Only visual 3D nodes are considered, such as [MeshInstance3D] or [DirectionalLight3D]. Use [method @GDScript.instance_from_id] to obtain the actual nodes. A scenario RID must be provided, which is available in the [World3D] you want to query. This forces an update for all resources queued to update. + Returns an array of object IDs intersecting with the provided 3D ray. Only visual 3D nodes are considered, such as [MeshInstance3D] or [DirectionalLight3D]. Use [method @GlobalScope.instance_from_id] to obtain the actual nodes. A scenario RID must be provided, which is available in the [World3D] you want to query. This forces an update for all resources queued to update. [b]Warning:[/b] This function is primarily intended for editor usage. For in-game use cases, prefer physics collision. </description> </method> @@ -2715,6 +2721,22 @@ Once finished with your RID, you will want to free the RID using the RenderingServer's [method free_rid] static method. </description> </method> + <method name="viewport_get_measured_render_time_cpu" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="viewport" type="RID"> + </argument> + <description> + </description> + </method> + <method name="viewport_get_measured_render_time_gpu" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="viewport" type="RID"> + </argument> + <description> + </description> + </method> <method name="viewport_get_render_info"> <return type="int"> </return> @@ -2852,6 +2874,16 @@ Currently unimplemented in Godot 3.x. </description> </method> + <method name="viewport_set_measure_render_time"> + <return type="void"> + </return> + <argument index="0" name="viewport" type="RID"> + </argument> + <argument index="1" name="enable" type="bool"> + </argument> + <description> + </description> + </method> <method name="viewport_set_msaa"> <return type="void"> </return> @@ -2917,6 +2949,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> 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/RichTextLabel.xml b/doc/classes/RichTextLabel.xml index 147e41bf1b..35eae32c7b 100644 --- a/doc/classes/RichTextLabel.xml +++ b/doc/classes/RichTextLabel.xml @@ -70,7 +70,14 @@ <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_total_character_count" qualifiers="const"> @@ -94,6 +101,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 +356,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 +478,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 +597,10 @@ <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_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"> 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 5fc1d0b895..cfe6e4f738 100644 --- a/doc/classes/SceneTree.xml +++ b/doc/classes/SceneTree.xml @@ -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"> @@ -260,7 +261,7 @@ The default [MultiplayerAPI] instance for this [SceneTree]. </member> <member name="multiplayer_poll" type="bool" setter="set_multiplayer_poll_enabled" getter="is_multiplayer_poll_enabled" default="true"> - If [code]true[/code] (default value), enables automatic polling of the [MultiplayerAPI] for this SceneTree during [signal idle_frame]. + If [code]true[/code] (default value), enables automatic polling of the [MultiplayerAPI] for this SceneTree during [signal process_frame]. If [code]false[/code], you need to manually call [method MultiplayerAPI.poll] to process network packets and deliver RPCs/RSETs. This allows running RPCs/RSETs in a different loop (e.g. physics, thread, specific time step) and for manual [Mutex] protection when accessing the [MultiplayerAPI] from threads. </member> <member name="network_peer" type="NetworkedMultiplayerPeer" setter="set_network_peer" getter="get_network_peer"> @@ -298,11 +299,6 @@ Emitted when files are dragged from the OS file manager and dropped in the game window. The arguments are a list of file paths and the identifier of the screen where the drag originated. </description> </signal> - <signal name="idle_frame"> - <description> - Emitted immediately before [method Node._process] is called on every node in the [SceneTree]. - </description> - </signal> <signal name="network_peer_connected"> <argument index="0" name="id" type="int"> </argument> @@ -350,6 +346,11 @@ Emitted immediately before [method Node._physics_process] is called on every node in the [SceneTree]. </description> </signal> + <signal name="process_frame"> + <description> + Emitted immediately before [method Node._process] is called on every node in the [SceneTree]. + </description> + </signal> <signal name="server_disconnected"> <description> Emitted whenever this [SceneTree]'s [member network_peer] disconnected from server. Only emitted on clients. 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/String.xml b/doc/classes/String.xml index cbaf1196e3..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"> @@ -135,13 +144,6 @@ Returns a copy of the string with indentation (leading tabs and spaces) removed. </description> </method> - <method name="is_empty"> - <return type="bool"> - </return> - <description> - Returns [code]true[/code] if the length of the string equals [code]0[/code]. - </description> - </method> <method name="ends_with"> <return type="bool"> </return> @@ -228,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"> @@ -276,6 +262,13 @@ If the string is a path to a file or directory, returns [code]true[/code] if the path is absolute. </description> </method> + <method name="is_empty"> + <return type="bool"> + </return> + <description> + Returns [code]true[/code] if the length of the string equals [code]0[/code]. + </description> + </method> <method name="is_rel_path"> <return type="bool"> </return> @@ -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/StyleBox.xml b/doc/classes/StyleBox.xml index 525dba0549..a01dfbd4b8 100644 --- a/doc/classes/StyleBox.xml +++ b/doc/classes/StyleBox.xml @@ -39,7 +39,7 @@ <method name="get_default_margin" qualifiers="const"> <return type="float"> </return> - <argument index="0" name="side" type="int" enum="Side"> + <argument index="0" name="margin" type="int" enum="Side"> </argument> <description> Returns the default margin of the specified [enum Side]. @@ -48,7 +48,7 @@ <method name="get_margin" qualifiers="const"> <return type="float"> </return> - <argument index="0" name="side" type="int" enum="Side"> + <argument index="0" name="margin" type="int" enum="Side"> </argument> <description> Returns the content margin offset for the specified [enum Side]. @@ -72,7 +72,7 @@ <method name="set_default_margin"> <return type="void"> </return> - <argument index="0" name="side" type="int" enum="Side"> + <argument index="0" name="margin" type="int" enum="Side"> </argument> <argument index="1" name="offset" type="float"> </argument> diff --git a/doc/classes/StyleBoxFlat.xml b/doc/classes/StyleBoxFlat.xml index 71f227dfb0..13ea7df294 100644 --- a/doc/classes/StyleBoxFlat.xml +++ b/doc/classes/StyleBoxFlat.xml @@ -27,7 +27,7 @@ <method name="get_border_width" qualifiers="const"> <return type="int"> </return> - <argument index="0" name="side" type="int" enum="Side"> + <argument index="0" name="margin" type="int" enum="Side"> </argument> <description> Returns the specified [enum Side]'s border width. @@ -52,7 +52,7 @@ <method name="get_expand_margin" qualifiers="const"> <return type="float"> </return> - <argument index="0" name="side" type="int" enum="Side"> + <argument index="0" name="margin" type="int" enum="Side"> </argument> <description> Returns the size of the specified [enum Side]'s expand margin. @@ -61,7 +61,7 @@ <method name="set_border_width"> <return type="void"> </return> - <argument index="0" name="side" type="int" enum="Side"> + <argument index="0" name="margin" type="int" enum="Side"> </argument> <argument index="1" name="width" type="int"> </argument> @@ -116,7 +116,7 @@ <method name="set_expand_margin"> <return type="void"> </return> - <argument index="0" name="side" type="int" enum="Side"> + <argument index="0" name="margin" type="int" enum="Side"> </argument> <argument index="1" name="size" type="float"> </argument> diff --git a/doc/classes/StyleBoxTexture.xml b/doc/classes/StyleBoxTexture.xml index 5b17f25978..895d0c357d 100644 --- a/doc/classes/StyleBoxTexture.xml +++ b/doc/classes/StyleBoxTexture.xml @@ -12,7 +12,7 @@ <method name="get_expand_margin_size" qualifiers="const"> <return type="float"> </return> - <argument index="0" name="side" type="int" enum="Side"> + <argument index="0" name="margin" type="int" enum="Side"> </argument> <description> Returns the expand margin size of the specified [enum Side]. @@ -21,7 +21,7 @@ <method name="get_margin_size" qualifiers="const"> <return type="float"> </return> - <argument index="0" name="side" type="int" enum="Side"> + <argument index="0" name="margin" type="int" enum="Side"> </argument> <description> Returns the margin size of the specified [enum Side]. @@ -54,7 +54,7 @@ <method name="set_expand_margin_size"> <return type="void"> </return> - <argument index="0" name="side" type="int" enum="Side"> + <argument index="0" name="margin" type="int" enum="Side"> </argument> <argument index="1" name="size" type="float"> </argument> @@ -65,7 +65,7 @@ <method name="set_margin_size"> <return type="void"> </return> - <argument index="0" name="side" type="int" enum="Side"> + <argument index="0" name="margin" type="int" enum="Side"> </argument> <argument index="1" name="size" type="float"> </argument> diff --git a/doc/classes/SurfaceTool.xml b/doc/classes/SurfaceTool.xml index 82ffe86251..331de4284e 100644 --- a/doc/classes/SurfaceTool.xml +++ b/doc/classes/SurfaceTool.xml @@ -31,15 +31,6 @@ Adds an index to index array if you are using indexed vertices. Does not need to be called before adding vertices. </description> </method> - <method name="add_smooth_group"> - <return type="void"> - </return> - <argument index="0" name="smooth" type="bool"> - </argument> - <description> - Specifies whether the current vertex (if using only vertex arrays) or current index (if also using index arrays) should use smooth normals for normal calculation. - </description> - </method> <method name="add_triangle_fan"> <return type="void"> </return> @@ -148,14 +139,24 @@ Removes the index array by expanding the vertex array. </description> </method> + <method name="generate_lod"> + <return type="PackedInt32Array"> + </return> + <argument index="0" name="nd_threshold" type="float"> + </argument> + <argument index="1" name="target_index_count" type="int" default="3"> + </argument> + <description> + </description> + </method> <method name="generate_normals"> <return type="void"> </return> <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"> @@ -173,6 +174,12 @@ <description> </description> </method> + <method name="get_max_axis_length" qualifiers="const"> + <return type="float"> + </return> + <description> + </description> + </method> <method name="get_skin_weight_count" qualifiers="const"> <return type="int" enum="SurfaceTool.SkinWeightCount"> </return> @@ -186,6 +193,12 @@ Shrinks the vertex array by creating an index array (avoids reusing vertices). </description> </method> + <method name="optimize_indices_for_cache"> + <return type="void"> + </return> + <description> + </description> + </method> <method name="set_bones"> <return type="void"> </return> @@ -251,6 +264,15 @@ <description> </description> </method> + <method name="set_smooth_group"> + <return type="void"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + Specifies whether the current vertex (if using only vertex arrays) or current index (if also using index arrays) should use smooth normals for normal calculation. + </description> + </method> <method name="set_tangent"> <return type="void"> </return> 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 c9ed1aaec9..52577e6102 100644 --- a/doc/classes/TabContainer.xml +++ b/doc/classes/TabContainer.xml @@ -137,6 +137,9 @@ </method> </methods> <members> + <member name="all_tabs_in_front" type="bool" setter="set_all_tabs_in_front" getter="is_all_tabs_in_front" default="false"> + If [code]true[/code], all tabs are drawn in front of the panel. If [code]false[/code], inactive tabs are drawn behind the panel. + </member> <member name="current_tab" type="int" setter="set_current_tab" getter="get_current_tab" default="0"> The current tab index. When set, this index's [Control] node's [code]visible[/code] property is set to [code]true[/code] and all others are set to [code]false[/code]. </member> @@ -149,9 +152,6 @@ <member name="tabs_visible" type="bool" setter="set_tabs_visible" getter="are_tabs_visible" default="true"> If [code]true[/code], tabs are visible. If [code]false[/code], tabs' content and titles are hidden. </member> - <member name="all_tabs_in_front" type="bool" setter="set_all_tabs_in_front" getter="is_all_tabs_in_front" default="false"> - If [code]true[/code], all tabs are drawn in front of the panel. If [code]false[/code], inactive tabs are drawn behind the panel. - </member> <member name="use_hidden_tabs_for_min_size" type="bool" setter="set_use_hidden_tabs_for_min_size" getter="get_use_hidden_tabs_for_min_size" default="false"> If [code]true[/code], children [Control] nodes that are hidden have their minimum size take into account in the total, instead of only the currently visible one. </member> @@ -198,18 +198,18 @@ <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_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> @@ -231,14 +231,14 @@ <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..0c7b992cbf 100644 --- a/doc/classes/Tabs.xml +++ b/doc/classes/Tabs.xml @@ -359,18 +359,18 @@ <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_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> @@ -382,14 +382,14 @@ </theme_item> <theme_item name="panel" type="StyleBox"> </theme_item> - <theme_item name="tab_bg" type="StyleBox"> - The style of an inactive tab. - </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..539f7afbd8 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,9 @@ <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_readonly_color" type="Color" default="Color( 0.88, 0.88, 0.88, 0.5 )"> </theme_item> - <theme_item name="font_color_selected" type="Color" default="Color( 0, 0, 0, 1 )"> + <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"> diff --git a/doc/classes/TextureProgressBar.xml b/doc/classes/TextureProgressBar.xml index cfc8f16648..b40759578f 100644 --- a/doc/classes/TextureProgressBar.xml +++ b/doc/classes/TextureProgressBar.xml @@ -12,7 +12,7 @@ <method name="get_stretch_margin" qualifiers="const"> <return type="int"> </return> - <argument index="0" name="side" type="int" enum="Side"> + <argument index="0" name="margin" type="int" enum="Side"> </argument> <description> </description> @@ -20,7 +20,7 @@ <method name="set_stretch_margin"> <return type="void"> </return> - <argument index="0" name="side" type="int" enum="Side"> + <argument index="0" name="margin" type="int" enum="Side"> </argument> <argument index="1" name="value" type="int"> </argument> 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/Tree.xml b/doc/classes/Tree.xml index 01818e2993..406bda412a 100644 --- a/doc/classes/Tree.xml +++ b/doc/classes/Tree.xml @@ -524,7 +524,7 @@ <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_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"> 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..0e4a76a1a9 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="arg0" 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/Variant.xml b/doc/classes/Variant.xml index cd76689ffe..775bd58bcf 100644 --- a/doc/classes/Variant.xml +++ b/doc/classes/Variant.xml @@ -17,7 +17,7 @@ - VisualScript tracks properties inside Variants as well, but it also uses static typing. The GUI interface enforces that properties have a particular type that doesn't change over time. - C# is statically typed, but uses the Mono [code]object[/code] type in place of Godot's Variant class when it needs to represent a dynamic value. [code]object[/code] is the Mono runtime's equivalent of the same concept. - The statically-typed language NativeScript C++ does not define a built-in Variant-like class. Godot's GDNative bindings provide their own godot::Variant class for users; Any point at which the C++ code starts interacting with the Godot runtime is a place where you might have to start wrapping data inside Variant objects. - The global [method @GDScript.typeof] function returns the enumerated value of the Variant type stored in the current variable (see [enum Variant.Type]). + The global [method @GlobalScope.typeof] function returns the enumerated value of the Variant type stored in the current variable (see [enum Variant.Type]). [codeblock] var foo = 2 match typeof(foo): diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml index fef2d7cedd..4159a38d96 100644 --- a/doc/classes/Vector2.xml +++ b/doc/classes/Vector2.xml @@ -66,7 +66,7 @@ <description> Returns this vector's angle with respect to the positive X axis, or [code](1, 0)[/code] vector, in radians. For example, [code]Vector2.RIGHT.angle()[/code] will return zero, [code]Vector2.DOWN.angle()[/code] will return [code]PI / 2[/code] (a quarter turn, or 90 degrees), and [code]Vector2(1, -1).angle()[/code] will return [code]-PI / 4[/code] (a negative eighth turn, or -45 degrees). - Equivalent to the result of [method @GDScript.atan2] when called with the vector's [member y] and [member x] as parameters: [code]atan2(y, x)[/code]. + Equivalent to the result of [method @GlobalScope.atan2] when called with the vector's [member y] and [member x] as parameters: [code]atan2(y, x)[/code]. </description> </method> <method name="angle_to"> @@ -196,7 +196,7 @@ <argument index="0" name="to" type="Vector2"> </argument> <description> - Returns [code]true[/code] if this vector and [code]v[/code] are approximately equal, by running [method @GDScript.is_equal_approx] on each component. + Returns [code]true[/code] if this vector and [code]v[/code] are approximately equal, by running [method @GlobalScope.is_equal_approx] on each component. </description> </method> <method name="is_normalized"> @@ -390,13 +390,20 @@ <description> </description> </method> + <method name="orthogonal"> + <return type="Vector2"> + </return> + <description> + Returns a perpendicular vector rotated 90 degrees counter-clockwise compared to the original, with the same length. + </description> + </method> <method name="posmod"> <return type="Vector2"> </return> <argument index="0" name="mod" type="float"> </argument> <description> - Returns a vector composed of the [method @GDScript.fposmod] of this vector's components and [code]mod[/code]. + Returns a vector composed of the [method @GlobalScope.fposmod] of this vector's components and [code]mod[/code]. </description> </method> <method name="posmodv"> @@ -405,7 +412,7 @@ <argument index="0" name="modv" type="Vector2"> </argument> <description> - Returns a vector composed of the [method @GDScript.fposmod] of this vector's components and [code]modv[/code]'s components. + Returns a vector composed of the [method @GlobalScope.fposmod] of this vector's components and [code]modv[/code]'s components. </description> </method> <method name="project"> @@ -432,7 +439,7 @@ <argument index="0" name="phi" type="float"> </argument> <description> - Returns the vector rotated by [code]phi[/code] radians. See also [method @GDScript.deg2rad]. + Returns the vector rotated by [code]phi[/code] radians. See also [method @GlobalScope.deg2rad]. </description> </method> <method name="round"> @@ -446,7 +453,7 @@ <return type="Vector2"> </return> <description> - Returns the vector with each component set to one or negative one, depending on the signs of the components, or zero if the component is zero, by calling [method @GDScript.sign] on each component. + Returns the vector with each component set to one or negative one, depending on the signs of the components, or zero if the component is zero, by calling [method @GlobalScope.sign] on each component. </description> </method> <method name="slerp"> @@ -479,13 +486,6 @@ Returns this vector with each component snapped to the nearest multiple of [code]step[/code]. This can also be used to round to an arbitrary number of decimals. </description> </method> - <method name="orthogonal"> - <return type="Vector2"> - </return> - <description> - Returns a perpendicular vector rotated 90 degrees counter-clockwise compared to the original, with the same length. - </description> - </method> </methods> <members> <member name="x" type="float" setter="" getter="" default="0.0"> diff --git a/doc/classes/Vector3.xml b/doc/classes/Vector3.xml index 46fd45f85f..2d129a2c86 100644 --- a/doc/classes/Vector3.xml +++ b/doc/classes/Vector3.xml @@ -171,7 +171,7 @@ <argument index="0" name="to" type="Vector3"> </argument> <description> - Returns [code]true[/code] if this vector and [code]v[/code] are approximately equal, by running [method @GDScript.is_equal_approx] on each component. + Returns [code]true[/code] if this vector and [code]v[/code] are approximately equal, by running [method @GlobalScope.is_equal_approx] on each component. </description> </method> <method name="is_normalized"> @@ -410,7 +410,7 @@ <argument index="0" name="mod" type="float"> </argument> <description> - Returns a vector composed of the [method @GDScript.fposmod] of this vector's components and [code]mod[/code]. + Returns a vector composed of the [method @GlobalScope.fposmod] of this vector's components and [code]mod[/code]. </description> </method> <method name="posmodv"> @@ -419,7 +419,7 @@ <argument index="0" name="modv" type="Vector3"> </argument> <description> - Returns a vector composed of the [method @GDScript.fposmod] of this vector's components and [code]modv[/code]'s components. + Returns a vector composed of the [method @GlobalScope.fposmod] of this vector's components and [code]modv[/code]'s components. </description> </method> <method name="project"> @@ -462,7 +462,7 @@ <return type="Vector3"> </return> <description> - 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 @GDScript.sign] on each component. + 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="slerp"> 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 7b513d56c3..8120ae539e 100644 --- a/doc/classes/Viewport.xml +++ b/doc/classes/Viewport.xml @@ -222,6 +222,8 @@ </member> <member name="handle_input_locally" type="bool" setter="set_handle_input_locally" getter="is_handling_input_locally" default="true"> </member> + <member name="lod_threshold" type="float" setter="set_lod_threshold" getter="get_lod_threshold" default="1.0"> + </member> <member name="msaa" type="int" setter="set_msaa" getter="get_msaa" enum="Viewport.MSAA" default="0"> The multisample anti-aliasing mode. A higher number results in smoother edges at the cost of significantly worse performance. A value of 4 is best unless targeting very high-end systems. </member> @@ -238,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> @@ -250,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> @@ -405,6 +409,16 @@ </constant> <constant name="DEBUG_DRAW_GI_BUFFER" value="17" enum="DebugDraw"> </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/WeakRef.xml b/doc/classes/WeakRef.xml index 07d82289a3..4140df5828 100644 --- a/doc/classes/WeakRef.xml +++ b/doc/classes/WeakRef.xml @@ -4,7 +4,7 @@ Holds an [Object], but does not contribute to the reference count if the object is a reference. </brief_description> <description> - A weakref can hold a [Reference], without contributing to the reference counter. A weakref can be created from an [Object] using [method @GDScript.weakref]. If this object is not a reference, weakref still works, however, it does not have any effect on the object. Weakrefs are useful in cases where multiple classes have variables that refer to each other. Without weakrefs, using these classes could lead to memory leaks, since both references keep each other from being released. Making part of the variables a weakref can prevent this cyclic dependency, and allows the references to be released. + A weakref can hold a [Reference], without contributing to the reference counter. A weakref can be created from an [Object] using [method @GlobalScope.weakref]. If this object is not a reference, weakref still works, however, it does not have any effect on the object. Weakrefs are useful in cases where multiple classes have variables that refer to each other. Without weakrefs, using these classes could lead to memory leaks, since both references keep each other from being released. Making part of the variables a weakref can prevent this cyclic dependency, and allows the references to be released. </description> <tutorials> </tutorials> diff --git a/doc/classes/XRController3D.xml b/doc/classes/XRController3D.xml index 345e5efdee..a4a86cc22a 100644 --- a/doc/classes/XRController3D.xml +++ b/doc/classes/XRController3D.xml @@ -19,13 +19,6 @@ If active, returns the name of the associated controller if provided by the AR/VR SDK used. </description> </method> - <method name="get_tracker_hand" qualifiers="const"> - <return type="int" enum="XRPositionalTracker.TrackerHand"> - </return> - <description> - Returns the hand holding this controller, if known. See [enum XRPositionalTracker.TrackerHand]. - </description> - </method> <method name="get_is_active" qualifiers="const"> <return type="bool"> </return> @@ -56,6 +49,13 @@ If provided by the [XRInterface], this returns a mesh associated with the controller. This can be used to visualize the controller. </description> </method> + <method name="get_tracker_hand" qualifiers="const"> + <return type="int" enum="XRPositionalTracker.TrackerHand"> + </return> + <description> + Returns the hand holding this controller, if known. See [enum XRPositionalTracker.TrackerHand]. + </description> + </method> <method name="is_button_pressed" qualifiers="const"> <return type="bool"> </return> diff --git a/doc/classes/XRPositionalTracker.xml b/doc/classes/XRPositionalTracker.xml index 36ff312e4d..36cd6e2ea0 100644 --- a/doc/classes/XRPositionalTracker.xml +++ b/doc/classes/XRPositionalTracker.xml @@ -12,13 +12,6 @@ <link title="VR tutorial index">https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link> </tutorials> <methods> - <method name="get_tracker_hand" qualifiers="const"> - <return type="int" enum="XRPositionalTracker.TrackerHand"> - </return> - <description> - Returns the hand holding this tracker, if known. See [enum TrackerHand] constants. - </description> - </method> <method name="get_joy_id" qualifiers="const"> <return type="int"> </return> @@ -47,6 +40,13 @@ Returns the world-space controller position. </description> </method> + <method name="get_tracker_hand" qualifiers="const"> + <return type="int" enum="XRPositionalTracker.TrackerHand"> + </return> + <description> + Returns the hand holding this tracker, if known. See [enum TrackerHand] constants. + </description> + </method> <method name="get_tracker_id" qualifiers="const"> <return type="int"> </return> @@ -68,6 +68,15 @@ Returns the tracker's type, which will be one of the values from the [enum XRServer.TrackerType] enum. </description> </method> + <method name="get_transform" qualifiers="const"> + <return type="Transform"> + </return> + <argument index="0" name="adjust_by_reference_frame" type="bool"> + </argument> + <description> + Returns the transform combining this device's orientation and position. + </description> + </method> <method name="is_tracking_orientation" qualifiers="const"> <return type="bool"> </return> @@ -82,15 +91,6 @@ Returns [code]true[/code] if this device is tracking position. </description> </method> - <method name="get_transform" qualifiers="const"> - <return type="Transform"> - </return> - <argument index="0" name="adjust_by_reference_frame" type="bool"> - </argument> - <description> - Returns the transform combining this device's orientation and position. - </description> - </method> </methods> <members> <member name="rumble" type="float" setter="set_rumble" getter="get_rumble" default="0.0"> diff --git a/drivers/alsa/audio_driver_alsa.cpp b/drivers/alsa/audio_driver_alsa.cpp index 5b0d2233e0..ea0cba6c52 100644 --- a/drivers/alsa/audio_driver_alsa.cpp +++ b/drivers/alsa/audio_driver_alsa.cpp @@ -153,7 +153,7 @@ Error AudioDriverALSA::init() { Error err = init_device(); if (err == OK) { - thread = Thread::create(AudioDriverALSA::thread_func, this); + thread.start(AudioDriverALSA::thread_func, this); } return err; @@ -291,16 +291,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 +306,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..c0233f41e1 100644 --- a/drivers/alsa/audio_driver_alsa.h +++ b/drivers/alsa/audio_driver_alsa.h @@ -40,7 +40,7 @@ #include <alsa/asoundlib.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..474f139bd6 100644 --- a/drivers/alsamidi/midi_driver_alsamidi.h +++ b/drivers/alsamidi/midi_driver_alsamidi.h @@ -42,7 +42,7 @@ #include <stdio.h> class MIDIDriverALSAMidi : public MIDIDriver { - Thread *thread; + Thread thread; Mutex mutex; Vector<snd_rawmidi_t *> connected_inputs; diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h index 2c95c7dbec..184267734a 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,7 +80,7 @@ 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 {} + 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) override {} /* SKY API */ @@ -93,17 +116,16 @@ public: 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) 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>(); } @@ -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,22 @@ 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) override {} + 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) 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_sdfgi(RID p_render_buffers, int p_region, const PagedArray<GeometryInstance *> &p_instances) override {} + 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) 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 +188,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; } @@ -370,6 +397,8 @@ 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(); } + RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const override { return RS::ShaderNativeSourceCode(); }; + /* COMMON MATERIAL API */ RID material_create() override { return RID(); } @@ -385,7 +414,7 @@ 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 */ @@ -397,6 +426,16 @@ public: return mesh_owner.make_rid(mesh); } + 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 @@ -525,6 +564,7 @@ public: 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 */ @@ -644,8 +684,8 @@ 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 */ @@ -712,10 +752,10 @@ public: /* LIGHTMAP CAPTURE */ #if 0 struct Instantiable { - SelfList<RendererSceneRender::InstanceBase>::List instance_list; + SelfList<RendererSceneRender::GeometryInstance>::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(); + SelfList<RendererSceneRender::GeometryInstance> *instances = instance_list.first(); while (instances) override { //instances->self()->base_changed(p_aabb, p_materials); instances = instances->next(); @@ -723,9 +763,9 @@ public: } _FORCE_INLINE_ void instance_remove_deps() override { - SelfList<RendererSceneRender::InstanceBase> *instances = instance_list.first(); + SelfList<RendererSceneRender::GeometryInstance> *instances = instance_list.first(); while (instances) override { - SelfList<RendererSceneRender::InstanceBase> *next = instances->next(); + SelfList<RendererSceneRender::GeometryInstance> *next = instances->next(); //instances->self()->base_removed(); instances = next; } @@ -828,8 +868,8 @@ 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 {} @@ -850,6 +890,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 {} diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp index 440b7d7f53..a5092c8c5c 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp +++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp @@ -287,7 +287,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 +581,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 +597,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 +616,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..2ddf8d2592 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.h +++ b/drivers/pulseaudio/audio_driver_pulseaudio.h @@ -40,7 +40,7 @@ #include <pulse/pulseaudio.h> class AudioDriverPulseAudio : public AudioDriver { - Thread *thread = nullptr; + Thread thread; Mutex mutex; pa_mainloop *pa_ml = nullptr; 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 474e801146..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) + "."); @@ -2134,7 +2213,16 @@ RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p VK_IMAGE_VIEW_TYPE_2D, }; - image_view_create_info.viewType = p_slice_type == TEXTURE_SLICE_CUBEMAP ? VK_IMAGE_VIEW_TYPE_CUBE : (p_slice_type == TEXTURE_SLICE_3D ? VK_IMAGE_VIEW_TYPE_3D : view_types[texture.type]); + image_view_create_info.viewType = view_types[texture.type]; + + if (p_slice_type == TEXTURE_SLICE_CUBEMAP) { + image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_CUBE; + } else if (p_slice_type == TEXTURE_SLICE_3D) { + image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_3D; + } else if (p_slice_type == TEXTURE_SLICE_2D_ARRAY) { + image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; + } + if (p_view.format_override == DATA_FORMAT_MAX || p_view.format_override == texture.format) { image_view_create_info.format = vulkan_formats[texture.format]; } else { @@ -2187,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); @@ -2232,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 { @@ -2257,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); @@ -2273,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; @@ -2354,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); @@ -2366,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; @@ -2386,9 +2502,16 @@ 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; } @@ -2599,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."); @@ -2626,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."); @@ -2647,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 @@ -2722,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; @@ -2739,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 @@ -2748,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; @@ -2761,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."); @@ -2785,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."); @@ -2799,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 @@ -2874,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; @@ -2891,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 @@ -2900,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; @@ -2913,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); @@ -2943,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; @@ -2990,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; @@ -3007,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; } @@ -3095,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; @@ -3107,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; @@ -3135,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; @@ -3142,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; @@ -3271,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); @@ -3314,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) { @@ -3366,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; } @@ -3382,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; @@ -3957,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; @@ -3973,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(), @@ -4052,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) { @@ -4173,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(), @@ -4221,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; @@ -5027,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."); } @@ -5047,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_ @@ -5068,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."); } @@ -5511,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); @@ -5629,7 +5895,7 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin_for_screen(Di vkCmdSetScissor(command_buffer, 0, 1, &scissor); - return ID_TYPE_DRAW_LIST; + return int64_t(ID_TYPE_DRAW_LIST) << ID_BASE_SHIFT; } Error RenderingDeviceVulkan::_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) { @@ -5682,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()); @@ -5813,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); @@ -5834,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; } @@ -5896,7 +6176,7 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu vkCmdSetScissor(command_buffer, 0, 1, &scissor); draw_list->viewport = Rect2i(viewport_offset, viewport_size); - return ID_TYPE_DRAW_LIST; + return int64_t(ID_TYPE_DRAW_LIST) << ID_BASE_SHIFT; } Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, DrawListID *r_split_ids, 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_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region, const Vector<RID> &p_storage_textures) { @@ -5925,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; } @@ -5993,7 +6273,7 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p for (uint32_t i = 0; i < p_splits; i++) { //take a command buffer and initialize it - VkCommandBuffer command_buffer = split_draw_list_allocators[p_splits].command_buffers[frame]; + VkCommandBuffer command_buffer = split_draw_list_allocators[i].command_buffers[frame]; VkCommandBufferInheritanceInfo inheritance_info; inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; @@ -6051,7 +6331,7 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p scissor.extent.height = viewport_size.height; vkCmdSetScissor(command_buffer, 0, 1, &scissor); - r_split_ids[i] = (DrawListID(1) << DrawListID(ID_TYPE_SPLIT_DRAW_LIST)) + i; + r_split_ids[i] = (int64_t(ID_TYPE_SPLIT_DRAW_LIST) << ID_BASE_SHIFT) + i; draw_list[i].viewport = Rect2i(viewport_offset, viewport_size); } @@ -6066,7 +6346,7 @@ RenderingDeviceVulkan::DrawList *RenderingDeviceVulkan::_get_draw_list_ptr(DrawL if (!draw_list) { return nullptr; - } else if (p_id == ID_TYPE_DRAW_LIST) { + } else if (p_id == (int64_t(ID_TYPE_DRAW_LIST) << ID_BASE_SHIFT)) { if (draw_list_split) { return nullptr; } @@ -6182,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(); @@ -6424,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."); @@ -6433,8 +6726,8 @@ void RenderingDeviceVulkan::draw_list_end() { //send all command buffers VkCommandBuffer *command_buffers = (VkCommandBuffer *)alloca(sizeof(VkCommandBuffer) * draw_list_count); for (uint32_t i = 0; i < draw_list_count; i++) { - vkEndCommandBuffer(draw_list->command_buffer); - command_buffers[i] = draw_list->command_buffer; + vkEndCommandBuffer(draw_list[i].command_buffer); + command_buffers[i] = draw_list[i].command_buffer; } vkCmdExecuteCommands(frames[frame].draw_command_buffer, draw_list_count, command_buffers); @@ -6460,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; @@ -6482,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; } @@ -6496,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 } @@ -6504,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; } @@ -6566,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 @@ -6603,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; @@ -6624,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; @@ -6654,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(); @@ -6755,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); @@ -6819,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; @@ -6839,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() { @@ -6988,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)."); @@ -7040,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); } @@ -7406,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; @@ -7445,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..f2d541754f 100644 --- a/drivers/wasapi/audio_driver_wasapi.cpp +++ b/drivers/wasapi/audio_driver_wasapi.cpp @@ -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.cpp b/drivers/windows/rw_lock_windows.cpp deleted file mode 100644 index 6f59e072bb..0000000000 --- a/drivers/windows/rw_lock_windows.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/*************************************************************************/ -/* rw_lock_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. */ -/*************************************************************************/ - -#if defined(WINDOWS_ENABLED) - -#include "rw_lock_windows.h" - -#include "core/error/error_macros.h" -#include "core/os/memory.h" - -#include <stdio.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); -} - -void RWLockWindows::write_unlock() { - ReleaseSRWLockExclusive(&lock); -} - -Error RWLockWindows::write_try_lock() { - if (TryAcquireSRWLockExclusive(&lock) == 0) { - return ERR_BUSY; - } else { - return OK; - } -} - -RWLock *RWLockWindows::create_func_windows() { - return memnew(RWLockWindows); -} - -void RWLockWindows::make_default() { - create_func = create_func_windows; -} - -RWLockWindows::RWLockWindows() { - InitializeSRWLock(&lock); -} - -RWLockWindows::~RWLockWindows() { -} - -#endif 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/xaudio2/audio_driver_xaudio2.cpp b/drivers/xaudio2/audio_driver_xaudio2.cpp index 3b3c3481b6..1bb8da769b 100644 --- a/drivers/xaudio2/audio_driver_xaudio2.cpp +++ b/drivers/xaudio2/audio_driver_xaudio2.cpp @@ -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/audio_stream_preview.cpp b/editor/audio_stream_preview.cpp index 2e0c3491f7..8be8735f3e 100644 --- a/editor/audio_stream_preview.cpp +++ b/editor/audio_stream_preview.cpp @@ -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; @@ -218,7 +219,8 @@ void AudioStreamPreviewGenerator::_notification(int p_what) { for (Map<ObjectID, Preview>::Element *E = previews.front(); E; E = E->next()) { if (!E->get().generating) { 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/create_dialog.cpp b/editor/create_dialog.cpp index dd5a87ff30..3a63100012 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -408,15 +408,15 @@ String CreateDialog::get_selected_type() { return selected->get_text(0); } -Object *CreateDialog::instance_selected() { +Variant CreateDialog::instance_selected() { TreeItem *selected = search_options->get_selected(); if (!selected) { - return nullptr; + return Variant(); } Variant md = selected->get_metadata(0); - Object *obj = nullptr; + Variant obj; if (md.get_type() != Variant::NIL) { String custom = md; if (ScriptServer::is_global_class(custom)) { @@ -434,13 +434,13 @@ Object *CreateDialog::instance_selected() { // Check if any Object-type property should be instantiated. List<PropertyInfo> pinfo; - obj->get_property_list(&pinfo); + ((Object *)obj)->get_property_list(&pinfo); for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { PropertyInfo pi = E->get(); if (pi.type == Variant::OBJECT && pi.usage & PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT) { Object *prop = ClassDB::instance(pi.class_name); - obj->set(pi.name, prop); + ((Object *)obj)->set(pi.name, prop); } } diff --git a/editor/create_dialog.h b/editor/create_dialog.h index b76155365f..b08cb72f14 100644 --- a/editor/create_dialog.h +++ b/editor/create_dialog.h @@ -102,7 +102,7 @@ protected: void _save_and_update_favorite_list(); public: - Object *instance_selected(); + Variant instance_selected(); String get_selected_type(); void set_base_type(const String &p_base) { base_type = p_base; } 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/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index 7569800a7e..2eef4636d6 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")); diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index 4c4dacbeb5..336bf26607 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--) { @@ -468,24 +458,25 @@ void EditorData::add_custom_type(const String &p_type, const String &p_inherits, custom_types[p_inherits].push_back(ct); } -Object *EditorData::instance_custom_type(const String &p_type, const String &p_inherits) { +Variant EditorData::instance_custom_type(const String &p_type, const String &p_inherits) { if (get_custom_types().has(p_inherits)) { for (int i = 0; i < get_custom_types()[p_inherits].size(); i++) { if (get_custom_types()[p_inherits][i].name == p_type) { Ref<Script> script = get_custom_types()[p_inherits][i].script; - Object *ob = ClassDB::instance(p_inherits); - ERR_FAIL_COND_V(!ob, nullptr); - if (ob->is_class("Node")) { - ob->call("set_name", p_type); + Variant ob = ClassDB::instance(p_inherits); + ERR_FAIL_COND_V(!ob, Variant()); + Node *n = Object::cast_to<Node>(ob); + if (n) { + n->set_name(p_type); } - ob->set_script(script); + ((Object *)ob)->set_script(script); return ob; } } } - return nullptr; + return Variant(); } void EditorData::remove_custom_type(const String &p_type) { @@ -867,18 +858,18 @@ StringName EditorData::script_class_get_base(const String &p_class) const { return script->get_language()->get_global_class_name(base_script->get_path()); } -Object *EditorData::script_class_instance(const String &p_class) { +Variant EditorData::script_class_instance(const String &p_class) { if (ScriptServer::is_global_class(p_class)) { - Object *obj = ClassDB::instance(ScriptServer::get_global_class_native_base(p_class)); + Variant obj = ClassDB::instance(ScriptServer::get_global_class_native_base(p_class)); if (obj) { Ref<Script> script = script_class_load_script(p_class); if (script.is_valid()) { - obj->set_script(script); + ((Object *)obj)->set_script(script); } return obj; } } - return nullptr; + return Variant(); } Ref<Script> EditorData::script_class_load_script(const String &p_class) const { diff --git a/editor/editor_data.h b/editor/editor_data.h index 42afc9e079..f14a3fb4e0 100644 --- a/editor/editor_data.h +++ b/editor/editor_data.h @@ -144,7 +144,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); @@ -171,7 +170,7 @@ public: void restore_editor_global_states(); void add_custom_type(const String &p_type, const String &p_inherits, const Ref<Script> &p_script, const Ref<Texture2D> &p_icon); - Object *instance_custom_type(const String &p_type, const String &p_inherits); + Variant instance_custom_type(const String &p_type, const String &p_inherits); void remove_custom_type(const String &p_type); const Map<String, Vector<CustomType>> &get_custom_types() const { return custom_types; } @@ -208,7 +207,7 @@ public: bool script_class_is_parent(const String &p_class, const String &p_inherits); StringName script_class_get_base(const String &p_class) const; - Object *script_class_instance(const String &p_class); + Variant script_class_instance(const String &p_class); Ref<Script> script_class_load_script(const String &p_class) const; diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index fd4423646f..24256b843e 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -732,6 +732,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 +1028,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 + "'."); diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 208f678947..4b68de26e7 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(); } @@ -1046,7 +1046,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 +1076,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 +1092,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 +1122,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 +1130,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 +1138,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); @@ -1477,20 +1470,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); @@ -2079,11 +2073,9 @@ EditorFileSystem::EditorFileSystem() { 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; diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h index c0e11a0402..fa0b89e667 100644 --- a/editor/editor_file_system.h +++ b/editor/editor_file_system.h @@ -127,7 +127,7 @@ class EditorFileSystem : public Node { }; bool use_threads; - Thread *thread; + Thread thread; static void _thread_func(void *_userdata); EditorFileSystemDirectory *new_filesystem; @@ -189,7 +189,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; 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..ac36b7e762 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -2506,22 +2506,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 +2534,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); diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp index 859292c573..7b94016fb6 100644 --- a/editor/editor_log.cpp +++ b/editor/editor_log.cpp @@ -101,8 +101,6 @@ void EditorLog::copy() { } void EditorLog::add_message(const String &p_msg, MessageType p_type) { - log->add_newline(); - bool restore = p_type != MSG_TYPE_STD; switch (p_type) { case MSG_TYPE_STD: { @@ -128,6 +126,7 @@ void EditorLog::add_message(const String &p_msg, MessageType p_type) { } log->add_text(p_msg); + log->add_newline(); if (restore) { log->pop(); diff --git a/modules/arkit/arkit_session_delegate.mm b/editor/editor_native_shader_source_visualizer.cpp index 97af5bf42c..ed2692190c 100644 --- a/modules/arkit/arkit_session_delegate.mm +++ b/editor/editor_native_shader_source_visualizer.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* arkit_session_delegate.mm */ +/* editor_native_shader_source_visualizer.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,29 +28,45 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "arkit_session_delegate.h" -#include "arkit_interface.h" +#include "editor_native_shader_source_visualizer.h" -@implementation ARKitSessionDelegate +#include "scene/gui/text_edit.h" -@synthesize arkit_interface; - -- (void)session:(ARSession *)session didAddAnchors:(NSArray<ARAnchor *> *)anchors { - for (ARAnchor *anchor in anchors) { - arkit_interface->_add_or_update_anchor(anchor); +void EditorNativeShaderSourceVisualizer::_inspect_shader(RID p_shader) { + if (versions) { + memdelete(versions); + versions = nullptr; } -} -- (void)session:(ARSession *)session didRemoveAnchors:(NSArray<ARAnchor *> *)anchors { - for (ARAnchor *anchor in anchors) { - arkit_interface->_remove_anchor(anchor); - } -} + RS::ShaderNativeSourceCode nsc = RS::get_singleton()->shader_get_native_source_code(p_shader); -- (void)session:(ARSession *)session didUpdateAnchors:(NSArray<ARAnchor *> *)anchors { - for (ARAnchor *anchor in anchors) { - arkit_interface->_add_or_update_anchor(anchor); + versions = memnew(TabContainer); + versions->set_v_size_flags(Control::SIZE_EXPAND_FILL); + versions->set_h_size_flags(Control::SIZE_EXPAND_FILL); + for (int i = 0; i < nsc.versions.size(); i++) { + TabContainer *vtab = memnew(TabContainer); + vtab->set_name("Version " + itos(i)); + vtab->set_v_size_flags(Control::SIZE_EXPAND_FILL); + vtab->set_h_size_flags(Control::SIZE_EXPAND_FILL); + versions->add_child(vtab); + for (int j = 0; j < nsc.versions[i].stages.size(); j++) { + TextEdit *vtext = memnew(TextEdit); + vtext->set_readonly(true); + vtext->set_name(nsc.versions[i].stages[j].name); + vtext->set_text(nsc.versions[i].stages[j].code); + vtext->set_v_size_flags(Control::SIZE_EXPAND_FILL); + vtext->set_h_size_flags(Control::SIZE_EXPAND_FILL); + vtab->add_child(vtext); + } } + add_child(versions); + popup_centered_ratio(); } -@end +void EditorNativeShaderSourceVisualizer::_bind_methods() { + ClassDB::bind_method("_inspect_shader", &EditorNativeShaderSourceVisualizer::_inspect_shader); +} +EditorNativeShaderSourceVisualizer::EditorNativeShaderSourceVisualizer() { + add_to_group("_native_shader_source_visualizer"); + set_title(TTR("Native Shader Source Inspector")); +} diff --git a/modules/icloud/icloud.h b/editor/editor_native_shader_source_visualizer.h index 7b7aa52b63..72a2f8baae 100644 --- a/modules/icloud/icloud.h +++ b/editor/editor_native_shader_source_visualizer.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* icloud.h */ +/* editor_native_shader_source_visualizer.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,33 +28,23 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef ICLOUD_H -#define ICLOUD_H +#ifndef EDITOR_NATIVE_SHADER_SOURCE_VISUALIZER_H +#define EDITOR_NATIVE_SHADER_SOURCE_VISUALIZER_H -#include "core/object/class_db.h" +#include "scene/gui/dialogs.h" +#include "scene/gui/tab_container.h" -class ICloud : public Object { - GDCLASS(ICloud, Object); +class EditorNativeShaderSourceVisualizer : public AcceptDialog { + GDCLASS(EditorNativeShaderSourceVisualizer, AcceptDialog) + TabContainer *versions = nullptr; - static ICloud *instance; - static void _bind_methods(); + void _inspect_shader(RID p_shader); - List<Variant> pending_events; +protected: + static void _bind_methods(); 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(); + EditorNativeShaderSourceVisualizer(); }; -#endif +#endif // EDITOR_NATIVE_SHADER_SOURCE_VISUALIZER_H diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 72d9aacef3..12d0d1db08 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -498,6 +498,11 @@ void EditorNode::_notification(int p_what) { 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); + + uint32_t directional_shadow_size = GLOBAL_GET("rendering/quality/directional_shadow/size"); + uint32_t directional_shadow_16_bits = GLOBAL_GET("rendering/quality/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/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"))); @@ -512,10 +517,11 @@ void EditorNode::_notification(int p_what) { 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 use_half_res_gi = GLOBAL_DEF("rendering/quality/gi/use_half_resolution", false); + RS::get_singleton()->gi_set_use_half_resolution(use_half_res_gi); + 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"); @@ -613,8 +619,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")); @@ -1850,6 +1856,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; } @@ -2123,7 +2130,10 @@ void EditorNode::_run(bool p_current, const String &p_custom) { if (scene->get_filename() == "") { current_option = -1; - _menu_option_confirm(FILE_SAVE_BEFORE_RUN, false); + _menu_option(FILE_SAVE_AS_SCENE); + // Set the option to save and run so when the dialog is accepted, the scene runs. + current_option = FILE_SAVE_AND_RUN; + file->set_title(TTR("Save scene before running...")); return; } @@ -2289,6 +2299,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(); @@ -2313,7 +2324,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 { @@ -2382,18 +2393,6 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { case FILE_SAVE_ALL_SCENES: { _save_all_scenes(); } break; - case FILE_SAVE_BEFORE_RUN: { - if (!p_confirmed) { - confirmation->get_cancel_button()->set_text(TTR("No")); - confirmation->get_ok_button()->set_text(TTR("Yes")); - confirmation->set_text(TTR("This scene has never been saved. Save before running?")); - confirmation->popup_centered(); - break; - } - - _menu_option(FILE_SAVE_AS_SCENE); - _menu_option_confirm(FILE_SAVE_AND_RUN, false); - } break; case FILE_EXPORT_PROJECT: { project_export->popup_export(); @@ -2607,15 +2606,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); @@ -2829,6 +2821,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(); @@ -2864,8 +2860,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; } @@ -3043,8 +3038,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) { @@ -3058,14 +3052,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; } @@ -3074,7 +3068,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()) { @@ -4712,8 +4706,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")); @@ -5148,9 +5142,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); } } @@ -5476,7 +5468,7 @@ 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; @@ -5500,9 +5492,7 @@ int EditorNode::execute_and_show_output(const String &p_title, const String &p_p int prev_len = 0; - eta.execute_output_thread = Thread::create(_execute_thread, &eta); - - ERR_FAIL_COND_V(!eta.execute_output_thread, 0); + eta.execute_output_thread.start(_execute_thread, &eta); while (!eta.done) { { @@ -5517,8 +5507,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) { @@ -5593,6 +5582,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 @@ -5772,7 +5763,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); @@ -5981,8 +5971,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); @@ -6025,7 +6015,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); @@ -6273,7 +6263,7 @@ 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); + p->add_icon_shortcut(gui_base->get_theme_icon("HelpSearch", "EditorIcons"), ED_SHORTCUT("editor/editor_help", TTR("Search")), HELP_SEARCH); 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); @@ -6528,6 +6518,9 @@ EditorNode::EditorNode() { center_split->connect("resized", callable_mp(this, &EditorNode::_vp_resized)); + native_shader_source_visualizer = memnew(EditorNativeShaderSourceVisualizer); + gui_base->add_child(native_shader_source_visualizer); + orphan_resources = memnew(OrphanResourcesDialog); gui_base->add_child(orphan_resources); diff --git a/editor/editor_node.h b/editor/editor_node.h index 0ef2e8cbfc..356ac0caac 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -34,6 +34,7 @@ #include "editor/editor_data.h" #include "editor/editor_export.h" #include "editor/editor_folding.h" +#include "editor/editor_native_shader_source_visualizer.h" #include "editor/editor_run.h" #include "editor/inspector_dock.h" #include "editor/property_editor.h" @@ -107,7 +108,7 @@ 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; @@ -125,7 +126,6 @@ private: FILE_SAVE_SCENE, FILE_SAVE_AS_SCENE, FILE_SAVE_ALL_SCENES, - FILE_SAVE_BEFORE_RUN, FILE_SAVE_AND_RUN, FILE_SHOW_IN_FILESYSTEM, FILE_IMPORT_SUBSCENE, @@ -323,6 +323,8 @@ private: String current_path; MenuButton *update_spinner; + EditorNativeShaderSourceVisualizer *native_shader_source_visualizer; + String defer_load_scene; Node *_last_instanced_scene; 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 690808ddac..4d8a4f46b2 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -68,16 +68,18 @@ void EditorPropertyText::_text_changed(const String &p_string) { } if (string_name) { - emit_changed(get_edited_property(), StringName(p_string), "", false); + emit_changed(get_edited_property(), StringName(p_string), "", true); } else { - emit_changed(get_edited_property(), p_string, "", false); + emit_changed(get_edited_property(), p_string, "", true); } } void EditorPropertyText::update_property() { String s = get_edited_object()->get(get_edited_property()); updating = true; - text->set_text(s); + if (text->get_text() != s) { + text->set_text(s); + } text->set_editable(!is_read_only()); updating = false; } @@ -133,9 +135,11 @@ void EditorPropertyMultilineText::_open_big_text() { void EditorPropertyMultilineText::update_property() { String t = get_edited_object()->get(get_edited_property()); - text->set_text(t); - if (big_text && big_text->is_visible_in_tree()) { - big_text->set_text(t); + if (text->get_text() != t) { + text->set_text(t); + if (big_text && big_text->is_visible_in_tree()) { + big_text->set_text(t); + } } } @@ -2145,7 +2149,9 @@ void EditorPropertyColor::_color_changed(const Color &p_color) { } void EditorPropertyColor::_popup_closed() { - emit_changed(get_edited_property(), picker->get_pick_color(), "", false); + if (picker->get_pick_color() != last_color) { + emit_changed(get_edited_property(), picker->get_pick_color(), "", false); + } } void EditorPropertyColor::_picker_created() { @@ -2158,6 +2164,10 @@ void EditorPropertyColor::_picker_created() { } } +void EditorPropertyColor::_picker_opening() { + last_color = picker->get_pick_color(); +} + void EditorPropertyColor::_bind_methods() { } @@ -2193,6 +2203,7 @@ EditorPropertyColor::EditorPropertyColor() { 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 ////////////////////// @@ -2545,35 +2556,32 @@ void EditorPropertyResource::_menu_option(int p_which) { return; } - Object *obj = nullptr; - RES res_temp; + Variant obj; if (ScriptServer::is_global_class(intype)) { obj = ClassDB::instance(ScriptServer::get_global_class_native_base(intype)); if (obj) { - res_temp = obj; Ref<Script> script = ResourceLoader::load(ScriptServer::get_global_class_path(intype)); if (script.is_valid()) { - obj->set_script(Variant(script)); + ((Object *)obj)->set_script(script); } } } else { obj = ClassDB::instance(intype); - res_temp = obj; } if (!obj) { obj = EditorNode::get_editor_data().instance_custom_type(intype, "Resource"); - res_temp = obj; } - ERR_BREAK(!res_temp.is_valid()); + Resource *resp = Object::cast_to<Resource>(obj); + ERR_BREAK(!resp); if (get_edited_object() && base_type != String() && base_type == "Script") { //make visual script the right type - res_temp->call("set_instance_base_type", get_edited_object()->get_class()); + resp->call("set_instance_base_type", get_edited_object()->get_class()); } - res = res_temp; + res = RES(resp); emit_changed(get_edited_property(), res); update_property(); diff --git a/editor/editor_properties.h b/editor/editor_properties.h index ab908244ba..4775259111 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -549,6 +549,9 @@ class EditorPropertyColor : public EditorProperty { void _color_changed(const Color &p_color); void _popup_closed(); void _picker_created(); + void _picker_opening(); + + Color last_color; protected: static void _bind_methods(); diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp index 29a929d179..8056846f52 100644 --- a/editor/editor_resource_preview.cpp +++ b/editor/editor_resource_preview.cpp @@ -424,26 +424,23 @@ 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) { + if (thread.is_started()) { exit = true; preview_sem.post(); while (!exited) { 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; diff --git a/editor/editor_resource_preview.h b/editor/editor_resource_preview.h index c119ccd99f..99c48967d8 100644 --- a/editor/editor_resource_preview.h +++ b/editor/editor_resource_preview.h @@ -70,7 +70,7 @@ class EditorResourcePreview : public Node { Mutex preview_mutex; Semaphore preview_sem; - Thread *thread; + Thread thread; volatile bool exit; volatile bool exited; 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_settings.cpp b/editor/editor_settings.cpp index 9b9b6bf628..9908f5727e 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -326,7 +326,26 @@ 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 <= 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 +353,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 +380,6 @@ 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); // Theme _initial_set("interface/theme/preset", "Default"); @@ -637,6 +659,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 +959,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 +990,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 +1265,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 { diff --git a/editor/editor_settings.h b/editor/editor_settings.h index 61ec8546aa..616a938a86 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; diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 0d24d5013d..8f877a4762 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(); @@ -375,18 +376,18 @@ 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); @@ -408,8 +409,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); @@ -485,8 +486,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 +551,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 +601,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 +613,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 +633,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 +659,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 +684,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); @@ -708,10 +709,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")); @@ -753,9 +754,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 +827,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 +835,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 +892,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 +902,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 +919,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 +933,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 +1024,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 +1040,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 +1049,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 +1064,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 +1099,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 +1120,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 +1209,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 +1262,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 fcf3e49a91..e1c66f43b9 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,16 @@ void FileSystemDock::_make_scene_confirm() { void FileSystemDock::_file_removed(String p_file) { emit_signal("file_removed", p_file); + + path = "res://"; + current_path->set_text(path); } void FileSystemDock::_folder_removed(String p_folder) { emit_signal("folder_removed", p_folder); + + path = "res://"; + current_path->set_text(path); } void FileSystemDock::_rename_operation_confirm() { @@ -1465,6 +1474,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 +1585,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 = "res://"; + current_path->set_text(path); } } @@ -1898,7 +1913,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected } void FileSystemDock::_resource_created() { - Object *c = new_resource_dialog->instance_selected(); + Variant c = new_resource_dialog->instance_selected(); ERR_FAIL_COND(!c); Resource *r = Object::cast_to<Resource>(c); @@ -1912,17 +1927,14 @@ void FileSystemDock::_resource_created() { memdelete(node); } - REF res(r); - editor->push_item(c); - - RES current_res = RES(r); + editor->push_item(r); String fpath = path; if (!fpath.ends_with("/")) { fpath = fpath.get_base_dir(); } - editor->save_resource_as(current_res, fpath); + editor->save_resource_as(RES(r), fpath); } void FileSystemDock::_search_changed(const String &p_text, const Control *p_from) { 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_scene.cpp b/editor/import/resource_importer_scene.cpp index ead1f7c3e9..9944712931 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -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/scene_importer_mesh.cpp b/editor/import/scene_importer_mesh.cpp index cd7d58c6f6..78a7cd84f1 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")) { 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/inspector_dock.cpp b/editor/inspector_dock.cpp index 311fa5206e..fbcd76a95f 100644 --- a/editor/inspector_dock.cpp +++ b/editor/inspector_dock.cpp @@ -270,14 +270,13 @@ void InspectorDock::_select_history(int p_idx) { } void InspectorDock::_resource_created() { - Object *c = new_resource_dialog->instance_selected(); + Variant c = new_resource_dialog->instance_selected(); ERR_FAIL_COND(!c); Resource *r = Object::cast_to<Resource>(c); ERR_FAIL_COND(!r); - REF res(r); - editor->push_item(c); + editor->push_item(r); } void InspectorDock::_resource_selected(const RES &p_res, const String &p_property) { diff --git a/editor/node_3d_editor_gizmos.cpp b/editor/node_3d_editor_gizmos.cpp index 96ebb131ad..bd825d0802 100644 --- a/editor/node_3d_editor_gizmos.cpp +++ b/editor/node_3d_editor_gizmos.cpp @@ -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; @@ -3854,8 +3852,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 +3937,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 +4000,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/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/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp index b2d143c416..d726cd031e 100644 --- a/editor/plugins/asset_library_editor_plugin.cpp +++ b/editor/plugins/asset_library_editor_plugin.cpp @@ -900,7 +900,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 +1364,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/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 67b7a2af79..d92837b68d 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(); } }; @@ -963,9 +963,24 @@ void CanvasItemEditor::_restore_canvas_item_state(List<CanvasItem *> p_canvas_it } void CanvasItemEditor::_commit_canvas_item_state(List<CanvasItem *> p_canvas_items, String action_name, bool commit_bones) { - undo_redo->create_action(action_name); + List<CanvasItem *> modified_canvas_items; for (List<CanvasItem *>::Element *E = p_canvas_items.front(); E; E = E->next()) { CanvasItem *canvas_item = E->get(); + Dictionary old_state = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item)->undo_state; + Dictionary new_state = canvas_item->_edit_get_state(); + + if (old_state.hash() != new_state.hash()) { + modified_canvas_items.push_back(canvas_item); + } + } + + if (modified_canvas_items.is_empty()) { + return; + } + + undo_redo->create_action(action_name); + for (List<CanvasItem *>::Element *E = modified_canvas_items.front(); E; E = E->next()) { + CanvasItem *canvas_item = E->get(); CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); undo_redo->add_do_method(canvas_item, "_edit_set_state", canvas_item->_edit_get_state()); undo_redo->add_undo_method(canvas_item, "_edit_set_state", se->undo_state); @@ -3134,16 +3149,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); @@ -4148,7 +4163,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")); @@ -5623,7 +5638,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; @@ -5764,7 +5779,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)); @@ -6598,7 +6613,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); @@ -6606,7 +6621,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/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..63bb785c5e 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -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); diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 3e8547439f..a3009731f9 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -2445,12 +2445,14 @@ void Node3DEditorViewport::_notification(int p_what) { //update shadow atlas if changed int shadowmap_size = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/size"); + bool shadowmap_16_bits = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/16_bits"); 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_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)); @@ -2491,6 +2493,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 +2831,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 +2840,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 +3052,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 +3078,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 +3105,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 +3236,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 +3328,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 +4027,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(); @@ -5222,6 +5266,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 +5394,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 +5472,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 +5506,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 +5552,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 +5608,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] = { @@ -5657,8 +5742,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 +5782,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 +5813,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 +5832,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 +5848,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 +5863,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 +5874,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 +5993,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 +6014,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 +6024,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; } diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index 0cefaa6557..9fb7488a0f 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -213,6 +213,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, @@ -585,7 +590,6 @@ private: ///// ToolMode tool_mode; - bool orthogonal; RenderingServer::ScenarioDebugMode scenario_debug; @@ -618,6 +622,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 diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 1af790c48d..216c0c3bef 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -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..f57c8fbd6b 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); diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index c05f55a115..05a1561f7d 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); @@ -339,7 +339,7 @@ void ShaderEditor::_menu_option(int p_option) { shader_editor->remove_all_bookmarks(); } break; case HELP_DOCS: { - OS::get_singleton()->shell_open("https://docs.godotengine.org/en/stable/tutorials/shading/shading_reference/index.html"); + OS::get_singleton()->shell_open("https://docs.godotengine.org/en/latest/tutorials/shaders/shader_reference/index.html"); } break; } if (p_option != SEARCH_FIND && p_option != SEARCH_REPLACE && p_option != SEARCH_GOTO_LINE) { diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp index ea58a4535b..e160e6ca0d 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.cpp +++ b/editor/plugins/skeleton_3d_editor_plugin.cpp @@ -383,6 +383,10 @@ 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.origin = body_transform.basis.xform(Vector3(0, 0, -half_height)); 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..d45011c8aa 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); diff --git a/editor/plugins/texture_3d_editor_plugin.cpp b/editor/plugins/texture_3d_editor_plugin.cpp index 099257daa1..04e6aa6fa8 100644 --- a/editor/plugins/texture_3d_editor_plugin.cpp +++ b/editor/plugins/texture_3d_editor_plugin.cpp @@ -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); diff --git a/editor/plugins/texture_layered_editor_plugin.cpp b/editor/plugins/texture_layered_editor_plugin.cpp index 3b95ed813f..2be300ad66 100644 --- a/editor/plugins/texture_layered_editor_plugin.cpp +++ b/editor/plugins/texture_layered_editor_plugin.cpp @@ -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); diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp index 53e127d4c8..36348f7753 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) { diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index dffa796e8d..6a16aa28a9 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -39,7 +39,10 @@ #include "scene/gui/split_container.h" void TileMapEditor::_node_removed(Node *p_node) { - if (p_node == 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)); + node = nullptr; } } diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp index deeab2fbc7..5ac7fe262f 100644 --- a/editor/plugins/tile_set_editor_plugin.cpp +++ b/editor/plugins/tile_set_editor_plugin.cpp @@ -2173,7 +2173,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; } diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 056562a7a7..5061067ded 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); } @@ -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/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..afbed0c610 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -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); @@ -2055,9 +2050,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 +2136,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 +2157,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 +2171,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,8 +2261,7 @@ 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(); @@ -2291,6 +2281,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++) { @@ -2380,6 +2375,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 @@ -2691,8 +2688,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_settings_editor.cpp b/editor/project_settings_editor.cpp index 98cdab0b70..4516180fa5 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -381,9 +381,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); diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp index 93689dd4cd..07312e42b4 100644 --- a/editor/property_editor.cpp +++ b/editor/property_editor.cpp @@ -262,7 +262,7 @@ void CustomPropertyEditor::_menu_option(int p_which) { return; } - Object *obj = ClassDB::instance(intype); + Variant obj = ClassDB::instance(intype); if (!obj) { if (ScriptServer::is_global_class(intype)) { @@ -280,7 +280,7 @@ void CustomPropertyEditor::_menu_option(int p_which) { res->call("set_instance_base_type", owner->get_class()); } - v = res; + v = obj; emit_signal("variant_changed"); } break; @@ -1064,7 +1064,7 @@ void CustomPropertyEditor::_type_create_selected(int p_idx) { String intype = inheritors_array[p_idx]; - Object *obj = ClassDB::instance(intype); + Variant obj = ClassDB::instance(intype); if (!obj) { if (ScriptServer::is_global_class(intype)) { @@ -1075,11 +1075,9 @@ void CustomPropertyEditor::_type_create_selected(int p_idx) { } ERR_FAIL_COND(!obj); + ERR_FAIL_COND(!Object::cast_to<Resource>(obj)); - Resource *res = Object::cast_to<Resource>(obj); - ERR_FAIL_COND(!res); - - v = res; + v = obj; emit_signal("variant_changed"); hide(); } @@ -1251,7 +1249,7 @@ void CustomPropertyEditor::_action_pressed(int p_which) { String intype = inheritors_array[0]; if (hint == PROPERTY_HINT_RESOURCE_TYPE) { - Object *obj = ClassDB::instance(intype); + Variant obj = ClassDB::instance(intype); if (!obj) { if (ScriptServer::is_global_class(intype)) { @@ -1262,10 +1260,9 @@ void CustomPropertyEditor::_action_pressed(int p_which) { } ERR_BREAK(!obj); - Resource *res = Object::cast_to<Resource>(obj); - ERR_BREAK(!res); + ERR_BREAK(!Object::cast_to<Resource>(obj)); - v = res; + v = obj; emit_signal("variant_changed"); hide(); } diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index f317ac581f..ac1beb1c37 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) { @@ -123,24 +120,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 +133,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; }; @@ -228,6 +214,7 @@ void SceneTreeDock::_perform_instance_scenes(const Vector<String> &p_files, Node } editor_data->get_undo_redo().commit_action(); + editor->push_item(instances[instances.size() - 1]); } void SceneTreeDock::_replace_with_branch_scene(const String &p_file, Node *base) { @@ -1935,7 +1922,7 @@ void SceneTreeDock::_selection_changed() { } void SceneTreeDock::_do_create(Node *p_parent) { - Object *c = create_dialog->instance_selected(); + Variant c = create_dialog->instance_selected(); ERR_FAIL_COND(!c); Node *child = Object::cast_to<Node>(c); @@ -2015,7 +2002,7 @@ void SceneTreeDock::_create() { Node *n = E->get(); ERR_FAIL_COND(!n); - Object *c = create_dialog->instance_selected(); + Variant c = create_dialog->instance_selected(); ERR_FAIL_COND(!c); Node *newnode = Object::cast_to<Node>(c); @@ -2153,7 +2140,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 diff --git a/editor/translations/af.po b/editor/translations/af.po index 0f26618d10..c537e790e7 100644 --- a/editor/translations/af.po +++ b/editor/translations/af.po @@ -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 "" @@ -5218,8 +5210,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 +5224,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 +6335,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 +6400,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 "" @@ -7390,6 +7402,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -11561,6 +11577,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 +12122,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 +12140,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 +12152,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 +12566,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 +12646,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 +12867,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 +12916,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..7af493c55a 100644 --- a/editor/translations/ar.po +++ b/editor/translations/ar.po @@ -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 "خروج من Ø§Ù„Ù…ÙØ¹Ø¯Ù„ØŸ" @@ -5169,10 +5161,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 +5183,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 +6296,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 +6361,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 "إزالة نقطة من المنØÙ†Ù‰" @@ -7322,6 +7335,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 "كائنات مرسومة" @@ -11563,6 +11581,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 +12122,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 +12143,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 +12159,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 +12654,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 +12757,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 +13017,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 +13078,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 +13111,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 +13376,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..b03e325ec5 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-05 09:20+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 @@ -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 "" @@ -2650,7 +2641,7 @@ msgstr "" #: editor/editor_node.cpp msgid "MeshLibrary..." -msgstr "" +msgstr "Библиотека Ñ Ð¿Ð¾Ð»Ð¸Ð³Ð¾Ð½Ð½Ð¸ мрежи…" #: editor/editor_node.cpp msgid "TileSet..." @@ -2767,6 +2758,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" @@ -3745,19 +3738,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 +3857,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 +3971,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 +4003,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 +4065,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 +4108,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 +4136,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 +4153,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 +4203,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 +4211,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 +4250,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 +4275,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 +4283,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 +4341,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 +4355,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 +4376,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 +4396,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 +4409,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 +4442,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 +4450,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 +4458,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 +4514,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 +4529,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 +4554,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 +4798,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." @@ -4906,14 +4901,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 +4966,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 +4976,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 +5032,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 +5147,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 +5242,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 +5252,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 +5465,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 +5473,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 +5672,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 +5774,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 +5819,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 +5841,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 +5861,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 +5908,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 +5917,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 +5936,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 +5959,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 +5982,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 +6022,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 +6042,7 @@ msgstr "" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Source Mesh:" -msgstr "" +msgstr "Източник за полигонна мрежа:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "X-Axis" @@ -6046,7 +6058,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 +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 "Преобразуване в CPUParticles2D" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6096,9 +6112,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 +6124,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 +6133,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 +6149,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 +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 "" @@ -7113,6 +7123,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 +7299,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,11 +7552,11 @@ 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." @@ -7747,9 +7760,8 @@ msgid "Sep.:" msgstr "" #: editor/plugins/texture_region_editor_plugin.cpp -#, fuzzy msgid "TextureRegion" -msgstr "Двуизмерна текÑтура" +msgstr "ТекÑтурна облаÑÑ‚" #: editor/plugins/theme_editor_plugin.cpp msgid "Add All Items" @@ -8006,9 +8018,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 +8034,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 +8270,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 +8302,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" @@ -10441,9 +10449,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 +10469,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 +10487,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 +10503,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 +10592,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 +10639,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 +10651,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 +10679,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 +10689,8 @@ msgid "" msgstr "" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Class Name:" -msgstr "КлаÑ:" +msgstr "Име на клаÑа:" #: editor/script_create_dialog.cpp msgid "Template:" @@ -10705,9 +10701,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 +10781,8 @@ msgid "Profiler" msgstr "" #: editor/script_editor_debugger.cpp -#, fuzzy msgid "Network Profiler" -msgstr "ИзнаÑÑне на проекта" +msgstr "Профилиране на мрежата" #: editor/script_editor_debugger.cpp msgid "Monitor" @@ -10815,9 +10809,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 +10981,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 +11014,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 +11149,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 +11217,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 +11257,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 +11338,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 +11464,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 +11498,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 +11510,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 +11530,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 +11566,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 +11598,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 +11664,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 +11704,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 +11722,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 +11734,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 +11886,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 +11903,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 +11942,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 +12032,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 +12047,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 +12122,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 +12167,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 +12216,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 +12236,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 +12246,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 +12270,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 +12292,8 @@ msgstr "" msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "" +"Ðе Ñе вижда нищо, тъй като полигонните мрежи не Ñа били Ñвързани към Ñтъпки " +"на изчертаване." #: scene/3d/particles.cpp msgid "" @@ -12288,9 +12302,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 +12339,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 +12358,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 +12476,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 +12525,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 +12558,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..53a1d59aa3 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-01 20:53+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 "নিরà§à¦¬à¦¾à¦šà¦¿à¦¤ টà§à¦°à§à¦¯à¦¾à¦•/পথ অপসারণ করà§à¦¨à¥¤" @@ -451,17 +450,15 @@ msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ (Anim) টà§à¦°à§à¦¯à¦¾à¦• যোগ ঠ#: 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 +469,6 @@ msgid "Clipboard is empty" msgstr "কà§à¦²à§€à¦ªà¦¬à§‹à¦°à§à¦¡ খালি" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Paste Tracks" msgstr "মানসমূহ পà§à¦°à¦¤à¦¿à¦²à§‡à¦ªà¦¨/পেসà§à¦Ÿ করà§à¦¨" @@ -484,6 +480,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,16 +494,23 @@ 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." @@ -569,9 +573,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" @@ -1487,14 +1490,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 +1775,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 +2030,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 +2493,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 +2544,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 +2594,10 @@ msgid "Quit" msgstr "পà§à¦°à¦¸à§à¦¥à¦¾à¦¨ করà§à¦¨" #: editor/editor_node.cpp +msgid "Yes" +msgstr "হà§à¦¯à¦¾à¦" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "à¦à¦¡à¦¿à¦Ÿà¦° হতে পà§à¦°à¦¸à§à¦¥à¦¾à¦¨ করবেন?" @@ -5502,8 +5492,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 +5506,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 +6694,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 +6768,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 "বকà§à¦°à¦°à§‡à¦–া হতে বিনà§à¦¦à§ অপসারণ করà§à¦¨" @@ -7812,6 +7822,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 "অবজেকà§à¦Ÿ আà¦à¦•া হয়েছে" @@ -12278,6 +12293,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 +12889,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 +12907,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 +12919,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 +13364,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 +13459,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 +13693,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 +13751,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 +13788,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 +14136,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..94fec8b3b1 100644 --- a/editor/translations/br.po +++ b/editor/translations/br.po @@ -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 "" @@ -4971,8 +4963,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 +4977,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 +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 "" @@ -6104,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 "" @@ -7064,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 "" @@ -11091,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 "" @@ -11586,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 @@ -11602,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 @@ -11614,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 @@ -12007,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 @@ -12087,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." @@ -12300,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 "" @@ -12345,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/ca.po b/editor/translations/ca.po index 3019abd016..c728113731 100644 --- a/editor/translations/ca.po +++ b/editor/translations/ca.po @@ -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?" @@ -5222,10 +5213,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 +5238,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 +6398,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 +6467,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" @@ -7454,6 +7466,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" @@ -11890,6 +11907,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 +12482,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 +12504,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 +12521,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 +13004,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 +13105,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 +13364,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 +13429,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 +13464,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 +13839,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..c3be08c016 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 @@ -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?" @@ -3915,19 +3907,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" @@ -5158,10 +5147,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 +5171,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 +6289,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 +6354,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" @@ -7307,6 +7320,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é" @@ -11525,6 +11543,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 +12081,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 +12105,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 +12119,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 +12593,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 +12693,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 +12950,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 +13013,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 +13046,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 +13087,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 +13371,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..2231930b01 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)" @@ -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?" @@ -4784,17 +4783,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 +4832,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 +4863,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 +4899,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 +4941,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 +4983,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 +4999,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 +5023,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 +5041,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 +5059,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 +5077,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 +5126,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 +5149,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 +5159,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 +5178,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 +5197,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." @@ -5218,14 +5225,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 +5247,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 +5272,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 +5301,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 +5312,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 +5333,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 +5345,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 +5355,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 +5369,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 +5415,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 +6497,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 +6562,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 "" @@ -7562,6 +7583,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -11826,6 +11851,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 +12412,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 +12430,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 +12442,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 +12892,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 +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." @@ -13143,6 +13217,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 +13274,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 +13310,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" diff --git a/editor/translations/de.po b/editor/translations/de.po index 016d676ee4..79b57dac4e 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. @@ -66,7 +66,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-16 01:28+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 +75,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 @@ -2012,10 +2012,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 +2451,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 +2498,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 +2549,10 @@ msgid "Quit" msgstr "Verlassen" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Ja" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Editor verlassen?" @@ -3993,19 +3985,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 +4762,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" @@ -5248,12 +5237,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 +5258,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 +6387,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 +6451,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" @@ -7414,6 +7426,11 @@ msgid "Yaw" msgstr "Gieren" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Größe: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Gezeichnete Objekte" @@ -7528,7 +7545,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 +7633,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 +7749,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 +7826,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" @@ -10280,7 +10297,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." @@ -11668,6 +11685,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 +12231,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 +12254,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 +12768,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 +12866,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 +13139,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 +13205,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 +13240,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 +13285,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 +13634,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..5c298ea575 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. @@ -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 "" @@ -4949,8 +4941,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 +4955,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 +6032,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 +6096,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 "" @@ -7042,6 +7052,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -11069,6 +11083,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 +11606,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 +11624,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 +11636,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 +12039,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 +12119,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 +12336,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 +12385,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..abbfbaedfc 100644 --- a/editor/translations/el.po +++ b/editor/translations/el.po @@ -1958,10 +1958,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 +2392,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 +2439,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 +2490,10 @@ msgid "Quit" msgstr "Έξοδος" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Îαι" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "ΤεÏματισμός του Ï€ÏογÏάμματος επεξεÏγασίας;" @@ -5186,10 +5178,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 +5204,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 +6336,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 +6401,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 "ΑφαίÏεση σημείου από την καμπÏλη" @@ -7372,6 +7385,11 @@ msgid "Yaw" msgstr "ΠαÏÎκκλιση" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "ΜÎγεθος: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "ΖωγÏαφισμÎνα αντικείμενα" @@ -11628,6 +11646,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 +12200,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 +12223,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 +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 "" +"Μη ÎγκυÏη διαδÏομή 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 +12727,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 +12831,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 +13094,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 +13161,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 +13194,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 +13578,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..64b727be90 100644 --- a/editor/translations/eo.po +++ b/editor/translations/eo.po @@ -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?" @@ -5068,8 +5059,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 +5073,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 +6159,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 +6224,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 "" @@ -7174,6 +7183,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -11239,6 +11252,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 +11785,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 +11803,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 +11815,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 +12219,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 +12299,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 +12516,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 +12565,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 +12600,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..c6f5ff06d7 100644 --- a/editor/translations/es.po +++ b/editor/translations/es.po @@ -14,7 +14,7 @@ # 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. @@ -55,11 +55,14 @@ # 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. 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-16 01:29+0000\n" "Last-Translator: Javier Ocampos <xavier.ocampos@gmail.com>\n" "Language-Team: Spanish <https://hosted.weblate.org/projects/godot-engine/" "godot/es/>\n" @@ -68,7 +71,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 @@ -2009,10 +2012,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 +2450,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 +2497,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 +2547,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?" @@ -3994,19 +3988,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" @@ -5250,12 +5241,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 +5262,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 +6392,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 +6456,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" @@ -7414,6 +7429,11 @@ msgid "Yaw" msgstr "Yaw" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Tamaño: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Objetos Dibujados" @@ -9747,7 +9767,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" @@ -11664,6 +11684,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 +12230,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 +12253,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 +12771,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 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 +12868,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 +13134,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 +13198,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 +13233,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 +13275,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 +13619,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..4f32171d5f 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-01-29 19:32+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-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -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?" @@ -2890,7 +2883,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" @@ -3949,19 +3942,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" @@ -5205,12 +5195,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 +5216,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 +6340,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 +6404,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" @@ -7363,6 +7377,11 @@ msgid "Yaw" msgstr "Yaw" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Tamaño: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Objetos Dibujados" @@ -11611,6 +11630,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 +12175,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 +12198,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 +12709,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 +12806,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 +13070,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 +13131,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 +13166,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 +13544,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..d0eb9f05e4 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 @@ -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?" @@ -2745,7 +2736,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 +2792,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 "" @@ -3033,7 +3023,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Merge With Existing" -msgstr "" +msgstr "Liida olemasolevaga" #: editor/editor_node.cpp msgid "Open & Run a Script" @@ -3324,7 +3314,7 @@ msgstr "" #: editor/editor_sub_scene.cpp msgid "Scene Path:" -msgstr "" +msgstr "Stseeni tee:" #: editor/editor_sub_scene.cpp msgid "Import From Node:" @@ -4963,7 +4953,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 +4995,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 +5009,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 +6086,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 +6150,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 "" @@ -6725,11 +6733,11 @@ msgstr "Käivita" #: 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" @@ -6869,7 +6877,7 @@ 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 @@ -6977,19 +6985,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 +7106,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 +7199,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 +7287,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 +9583,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?" @@ -9639,7 +9656,7 @@ msgstr "Uus projekt" #: editor/project_manager.cpp msgid "Remove Missing" -msgstr "" +msgstr "Eemalda puuduvad" #: editor/project_manager.cpp msgid "Templates" @@ -9651,7 +9668,7 @@ msgstr "" #: editor/project_manager.cpp msgid "Can't run project" -msgstr "" +msgstr "Projekti ei saa käivitada" #: editor/project_manager.cpp msgid "" @@ -10724,7 +10741,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 +10757,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 +10797,7 @@ msgstr "Ressursi tee" #: editor/script_editor_debugger.cpp msgid "Type" -msgstr "" +msgstr "Tüüp" #: editor/script_editor_debugger.cpp msgid "Format" @@ -10813,7 +10830,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 +11148,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 +11671,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 +11689,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 +11701,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 +12104,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 +12185,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 +12402,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 +12451,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..f5557a0f3c 100644 --- a/editor/translations/eu.po +++ b/editor/translations/eu.po @@ -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 "" @@ -4970,8 +4962,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 +4976,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 +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 "" @@ -6103,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 "" @@ -7063,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 "" @@ -11100,6 +11115,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 +11638,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 +11656,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 +11668,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 +12071,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 +12151,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 +12368,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 +12418,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..7445611ef2 100644 --- a/editor/translations/fa.po +++ b/editor/translations/fa.po @@ -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 "خروج از ویرایشگر؟" @@ -5156,8 +5148,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 +5162,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 +6291,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 +6356,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 "" @@ -7367,6 +7379,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -11665,6 +11681,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 +12250,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 +12268,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 +12280,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 +12732,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 +12823,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 +13058,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 +13115,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 +13151,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 "جستجوی متن" diff --git a/editor/translations/fi.po b/editor/translations/fi.po index 4ff9685447..765ce4810c 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-01-21 11:57+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-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -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?" @@ -3906,19 +3898,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" @@ -5160,12 +5149,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 +5169,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 +6291,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 +6355,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ä" @@ -7315,6 +7327,11 @@ msgid "Yaw" msgstr "Käännös (yaw)" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Koko: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Objekteja piirretty" @@ -11554,6 +11571,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 +12111,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 +12132,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 +12631,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 +12728,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 +12990,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 +13052,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 +13087,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 +13129,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 +13470,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..ef79d29343 100644 --- a/editor/translations/fil.po +++ b/editor/translations/fil.po @@ -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 "" @@ -4967,8 +4959,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 +4973,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 +6053,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 +6117,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 "" @@ -7064,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 "" @@ -11098,6 +11112,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 +11638,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 +11656,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 +11668,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 +12071,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 +12151,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 +12368,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 +12417,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 +12449,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..4493eff913 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 @@ -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 ?" @@ -5277,13 +5269,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 +5289,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 +6425,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 +6489,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" @@ -7449,6 +7463,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" @@ -11709,6 +11727,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 +12276,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 +12300,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 +12825,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 +12921,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 +13190,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 +13255,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 +13290,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 +13336,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 +13683,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..206dad7441 100644 --- a/editor/translations/ga.po +++ b/editor/translations/ga.po @@ -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 "" @@ -4964,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 @@ -4979,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" @@ -6038,6 +6048,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 +6112,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 "" @@ -7058,6 +7068,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -11093,6 +11107,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 +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 @@ -11608,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 @@ -11620,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 @@ -12013,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 @@ -12093,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." @@ -12306,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 "" @@ -12351,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/gl.po b/editor/translations/gl.po new file mode 100644 index 0000000000..c3efe67d46 --- /dev/null +++ b/editor/translations/gl.po @@ -0,0 +1,12479 @@ +# 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. +# +# Andy Barcia <andybarcia4@gmail.com>, 2021. +msgid "" +msgstr "" +"Project-Id-Version: Godot Engine editor\n" +"PO-Revision-Date: 2021-02-05 09:20+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 "" + +#: 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 "" + +#: 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 "" + +#: 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 +#: 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 "" + +#: editor/animation_track_editor_plugins.cpp +msgid "Change Audio Track Clip End Offset" +msgstr "" + +#: 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 "" + +#: 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 "" +"A escena '%s' agora mesmo está sendo editada.\n" +"Os cambios so 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 so 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 "" + +#: 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 "" + +#: 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 "" + +#: 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 "Activar" + +#: 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 "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 "" + +#: 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 "" + +#: 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: 'res://addons/%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/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 "" + +#: 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 "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 +#: 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 sha256 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/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/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 "" + +#: 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 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 "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 "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 "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 "" + +#: 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/he.po b/editor/translations/he.po index 57746c75b0..fc4ba10dc4 100644 --- a/editor/translations/he.po +++ b/editor/translations/he.po @@ -1966,10 +1966,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 +2388,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 +2435,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 +2484,10 @@ msgid "Quit" msgstr "יצי××”" #: editor/editor_node.cpp +msgid "Yes" +msgstr "כן" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "לצ×ת מהעורך?" @@ -5171,10 +5163,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 +5183,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" @@ -6306,6 +6318,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 +6383,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 "" @@ -7379,6 +7392,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -11592,6 +11609,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 +12144,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 +12162,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 +12178,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 +12634,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 +12729,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 +12979,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 +13039,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 +13072,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 +13285,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..08829557bb 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 @@ -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 "संपादक से बाहर निकलें?" @@ -2810,6 +2808,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 @@ -3395,7 +3397,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 +3680,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 +3716,7 @@ msgstr "खà¥à¤²à¥‡ दृशà¥à¤¯" #: editor/filesystem_dock.cpp msgid "Instance" -msgstr "" +msgstr "इनसà¥à¤Ÿà¤¨à¥à¤¸" #: editor/filesystem_dock.cpp msgid "Add to Favorites" @@ -3725,11 +3732,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 +3744,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 +3753,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 +3771,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 +3798,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 +3893,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 +3917,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 +3942,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):" @@ -5097,8 +5107,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 +5121,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 +6204,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 +6269,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 +7244,11 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "आकार: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -11342,6 +11377,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 +11916,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 +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 @@ -11879,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 @@ -12279,27 +12356,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 +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." @@ -12574,6 +12657,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 +12706,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 +12742,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..95f2844a22 100644 --- a/editor/translations/hr.po +++ b/editor/translations/hr.po @@ -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 "" @@ -4975,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 @@ -4990,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" @@ -6048,6 +6058,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 +6122,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 "" @@ -7068,6 +7078,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -11110,6 +11124,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 +11654,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 +11672,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 +11684,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 +12087,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 +12167,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 +12384,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 +12433,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..e774fec26d 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 @@ -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?" @@ -5134,10 +5126,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 +5152,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 +6252,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 +6317,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" @@ -7234,7 +7247,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 +7282,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" @@ -11334,6 +11352,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 +11886,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 +11904,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 +11916,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 +12323,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 +12408,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 +12625,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 +12679,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 +12713,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..923b836555 100644 --- a/editor/translations/id.po +++ b/editor/translations/id.po @@ -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?" @@ -5177,10 +5169,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 +5191,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 +6317,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 +6382,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" @@ -7347,6 +7360,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" @@ -11603,6 +11621,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 +12167,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 +12192,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 +12210,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 +12686,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 +12782,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 +13033,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 +13099,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 +13132,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..8ab4fd9ec3 100644 --- a/editor/translations/is.po +++ b/editor/translations/is.po @@ -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 "" @@ -5019,8 +5011,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 +5025,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 +6113,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 +6177,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 "" @@ -7129,6 +7139,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -11212,6 +11226,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 +11759,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 +11777,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 +11789,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 +12192,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 +12272,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 +12489,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 +12538,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..3bc0ebac67 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,14 +52,14 @@ # 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. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-12-22 21:12+0000\n" +"PO-Revision-Date: 2021-02-01 20:53+0000\n" "Last-Translator: Lorenzo Cerqua <lorenzocerqua@tutanota.com>\n" "Language-Team: Italian <https://hosted.weblate.org/projects/godot-engine/" "godot/it/>\n" @@ -68,7 +68,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 @@ -190,9 +190,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 +202,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 +308,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 +332,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 +353,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 +390,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 +414,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 +438,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 +462,28 @@ 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 +#, fuzzy 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 una curva di Bézier (nessuna sotto-proprietà adatta)" #: 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 +491,22 @@ 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 +#, fuzzy 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 è possibile aggiungere una chiave di " +"chiamata di 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 +514,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,20 +522,21 @@ 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 +#, fuzzy msgid "" "This animation belongs to an imported scene, so changes to imported tracks " "will not be saved.\n" @@ -569,14 +548,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" +"Quest'animazione appartiene a una scena importata, eventuali modifiche fatte " +"alle tracce importate non verranno 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 la possibilità di aggiungere ulteriori tracce, andare nelle " +"impostazioni d'importazione della scena, impostare\n" +"\"Animation > Storage\" su \"Files\", attivare \"Animation > Keep Custom " +"Tracks\" e infine reimportare la scena.\n" +"Altrimenti, usare una preimpostazione che importi le animazioni in file " "separati." #: editor/animation_track_editor.cpp @@ -593,11 +572,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,25 +603,26 @@ 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 +#, fuzzy msgid "Duplicate Transposed" msgstr "Duplica trasposto" @@ -651,20 +631,22 @@ msgid "Delete Selection" msgstr "Elimina la selezione" #: editor/animation_track_editor.cpp +#, fuzzy msgid "Go to Next Step" msgstr "Va' al passo successivo" #: editor/animation_track_editor.cpp +#, fuzzy msgid "Go to Previous Step" msgstr "Va' al passo 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 +654,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 +662,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 +678,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 +690,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" @@ -733,31 +715,33 @@ 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 +#, fuzzy msgid "Change Audio Track Clip Start Offset" -msgstr "Cambia Offset di Inizio della Clip della Traccia Audio" +msgstr "Cambia lo scostamento dell'inizio della traccia audio" #: editor/animation_track_editor_plugins.cpp +#, fuzzy msgid "Change Audio Track Clip End Offset" -msgstr "Cambia offset di fine della clip della traccia audio" +msgstr "Cambia lo scostamento della fine della 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 +749,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 +761,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" @@ -2028,10 +2012,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 +2453,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 +2500,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 +2549,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?" @@ -4010,19 +3986,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" @@ -5266,13 +5239,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 +5260,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 +6392,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 +6456,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" @@ -7434,6 +7430,11 @@ msgid "Yaw" msgstr "Imbardata" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Dimensione: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Oggetti disegnati" @@ -11686,6 +11687,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 +12232,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 +12254,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 +12774,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 +12872,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 +13132,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 +13195,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 +13231,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 +13611,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..d960e0cc32 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,15 +29,15 @@ # 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. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-12-27 02:25+0000\n" -"Last-Translator: nitenook <admin@alterbaum.net>\n" +"PO-Revision-Date: 2021-01-22 10:21+0000\n" +"Last-Translator: Wataru Onuki <bettawat@yahoo.co.jp>\n" "Language-Team: Japanese <https://hosted.weblate.org/projects/godot-engine/" "godot/ja/>\n" "Language: ja\n" @@ -45,7 +45,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-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -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 "エディタを終了ã—ã¾ã™ã‹ï¼Ÿ" @@ -3933,19 +3925,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" @@ -5181,12 +5170,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 +5190,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 +6310,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 +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 "曲線ã‹ã‚‰ãƒã‚¤ãƒ³ãƒˆã‚’除去" @@ -7333,6 +7345,11 @@ msgid "Yaw" msgstr "ヨー" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "サイズ: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "æç”»ã•れãŸã‚ªãƒ–ジェクト" @@ -7466,7 +7483,7 @@ msgstr "オーディオリスナー" #: editor/plugins/spatial_editor_plugin.cpp msgid "Enable Doppler" -msgstr "ドップラー効果を有効化ã™ã‚‹" +msgstr "ドップラー効果を有効化" #: editor/plugins/spatial_editor_plugin.cpp msgid "Cinematic Preview" @@ -11560,6 +11577,39 @@ 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 msgid "Class name can't be a reserved keyword" msgstr "クラスåを予約ã‚ーワードã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" @@ -12074,12 +12124,17 @@ msgid "Select device from the list" msgstr "一覧ã‹ã‚‰ãƒ‡ãƒã‚¤ã‚¹ã‚’é¸æŠž" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." -msgstr "ADB実行å¯èƒ½ãƒ•ァイルãŒã‚¨ãƒ‡ã‚£ã‚¿è¨å®šã§è¨å®šã•れã¦ã„ã¾ã›ã‚“。" +#, fuzzy +msgid "Unable to find the 'apksigner' tool." +msgstr "zipalign ツールãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。" #: 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,11 +12145,13 @@ 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パスãŒå¿…è¦ã§ã™ã€‚" +#, 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 @@ -12102,12 +12159,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." +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 "" -"Android ビルド テンプレートãŒãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã¾ã›ã‚“。[プãƒ" -"ジェクト] メニューã‹ã‚‰ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¾ã™ã€‚" #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12580,28 +12646,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 "(Time Left: %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 "" @@ -12678,6 +12748,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 +13008,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 +13069,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 +13102,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 +13141,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 +13486,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..81e843c723 100644 --- a/editor/translations/ka.po +++ b/editor/translations/ka.po @@ -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 "" @@ -5145,8 +5137,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 +5151,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 +6258,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 +6323,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 "" @@ -7295,6 +7307,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -11440,6 +11456,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 +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 @@ -11968,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 @@ -11980,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 @@ -12380,27 +12436,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 +12516,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 +12737,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 +12786,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..c5b4f3c701 100644 --- a/editor/translations/ko.po +++ b/editor/translations/ko.po @@ -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 "편집기를 ëŒê¹Œìš”?" @@ -5138,10 +5130,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 +5152,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 +6264,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 +6329,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 "ê³¡ì„ ì—서 ì ì‚ì œ" @@ -7290,6 +7303,11 @@ msgid "Yaw" msgstr "ìš”" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "í¬ê¸°: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "ê·¸ë ¤ì§„ ê°ì²´" @@ -11488,6 +11506,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 +12050,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 +12070,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 +12084,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 +12547,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 +12648,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 +12904,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 +12965,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 +12998,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 +13365,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..c1c872988f 100644 --- a/editor/translations/lt.po +++ b/editor/translations/lt.po @@ -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 "" @@ -5113,8 +5105,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 +5119,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 +6219,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 +6284,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 "" @@ -7257,6 +7269,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -11409,6 +11425,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 +11965,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 +11983,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 +11995,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 +12405,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 +12485,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 +12709,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 +12758,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." diff --git a/editor/translations/lv.po b/editor/translations/lv.po index 7c30135407..09379f2903 100644 --- a/editor/translations/lv.po +++ b/editor/translations/lv.po @@ -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 "" @@ -5004,8 +4996,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 +5010,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 +6088,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 +6153,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 "" @@ -7114,6 +7126,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -11219,6 +11235,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 +11766,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 +11784,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 +11796,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 +12205,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 +12285,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 +12503,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 +12552,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..9c110afb2d 100644 --- a/editor/translations/mi.po +++ b/editor/translations/mi.po @@ -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 "" @@ -4947,8 +4939,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 +4953,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 +6030,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 +6094,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 "" @@ -7040,6 +7050,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -11067,6 +11081,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 +11604,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 +11622,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 +11634,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 +12037,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 +12117,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 +12334,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 +12383,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..47bb481995 --- /dev/null +++ b/editor/translations/mk.po @@ -0,0 +1,12424 @@ +# 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 +#: 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: 'res://addons/%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/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 "" + +#: 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 "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 +#: 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 sha256 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/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/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 "" + +#: 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 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 "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 "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 "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..0791218b36 100644 --- a/editor/translations/ml.po +++ b/editor/translations/ml.po @@ -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 "" @@ -4962,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 @@ -4977,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" @@ -6036,6 +6046,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 +6110,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 "" @@ -7056,6 +7066,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -11084,6 +11098,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 +11622,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 +11640,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 +11652,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 +12055,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 +12135,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 +12352,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 +12401,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..2d2ddb2deb 100644 --- a/editor/translations/mr.po +++ b/editor/translations/mr.po @@ -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 "" @@ -4954,8 +4946,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 +4960,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 +6037,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 +6101,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 "" @@ -7047,6 +7057,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -11075,6 +11089,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 +11612,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 +11630,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 +11642,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 +12045,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 +12125,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 +12342,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 +12391,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..e121414574 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 @@ -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,63 @@ 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'." 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 +2602,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 +2623,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 +2730,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 +2876,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 +2898,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 +2943,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 +2960,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 +2976,80 @@ 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 "" +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 +#, fuzzy msgid "Search" -msgstr "" +msgstr "Cari" #: 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 +3060,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 +3167,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 +3183,234 @@ 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 "" +msgstr "Buka & Jalankan Skrip" #: 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 +3419,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 @@ -3298,41 +3459,48 @@ msgstr "" #: 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 +#, 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 +3508,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:" @@ -5070,8 +5270,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 +5284,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 +6367,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 +6431,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 "" @@ -7170,6 +7388,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 "" @@ -10128,9 +10351,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:" @@ -11220,6 +11442,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 +11969,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 +11987,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 +11999,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 +12402,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 +12482,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 +12699,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 +12748,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 +12781,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..b597c27fe1 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 @@ -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?" @@ -2745,14 +2737,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 +3063,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 +3076,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 +3089,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 @@ -5458,8 +5446,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 +5460,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 +6631,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 +6696,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 +7007,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" @@ -7725,6 +7732,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 +8062,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 +8233,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 @@ -11725,7 +11735,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 +12052,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 +12619,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 +12637,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 +12649,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 +13065,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 +13148,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 +13370,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 +13420,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 +13455,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 +13691,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..33362f4e57 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-01 20:53+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 @@ -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?" @@ -3766,6 +3758,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 +3955,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" @@ -5207,10 +5201,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 +5225,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 +5314,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 +5337,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 +6344,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 +6408,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 +6636,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 +6695,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" @@ -7376,6 +7382,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" @@ -8240,13 +8251,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 +8411,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." @@ -8782,9 +8789,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 +8810,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 +9539,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 +9906,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 "" @@ -10511,19 +10516,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 +10572,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 +10634,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" @@ -11638,6 +11638,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 +12183,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 +12203,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." @@ -12657,28 +12698,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 "" @@ -12753,6 +12799,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." @@ -13010,6 +13060,10 @@ 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." @@ -13069,6 +13123,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 +13156,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..334b5b903e 100644 --- a/editor/translations/or.po +++ b/editor/translations/or.po @@ -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 "" @@ -4953,8 +4945,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 +4959,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 +6036,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 +6100,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 "" @@ -7046,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 "" @@ -11073,6 +11087,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 +11610,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 +11628,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 +11640,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 +12043,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 +12123,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 +12340,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 +12389,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..9d783625b9 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,12 @@ # Piotr Grodzki <ziemniakglados@gmail.com>, 2020. # Dzejkop <jakubtrad@gmail.com>, 2020. # Mateusz Grzonka <alpinus4@gmail.com>, 2020. +# gnu-ewm <gnu.ewm@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-01 20:54+0000\n" "Last-Translator: Tomek <kobewi4e@gmail.com>\n" "Language-Team: Polish <https://hosted.weblate.org/projects/godot-engine/" "godot/pl/>\n" @@ -59,7 +60,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-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -903,7 +904,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 +1982,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 +2416,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 +2463,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 +2512,10 @@ msgid "Quit" msgstr "Wyjdź" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Tak" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Zamknąć edytor?" @@ -3940,19 +3933,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 +4198,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." @@ -5193,12 +5183,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 +5203,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 +6326,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 +6390,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" @@ -7348,6 +7361,11 @@ msgid "Yaw" msgstr "Odchylenie" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Rozmiar: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Narysowane obiekty" @@ -10141,15 +10159,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" @@ -11585,6 +11603,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 +12142,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 +12165,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 +12668,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 +12767,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 +13027,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 +13088,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 +13123,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 +13164,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 +13505,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..f8ea72a750 100644 --- a/editor/translations/pr.po +++ b/editor/translations/pr.po @@ -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 "" @@ -5122,8 +5114,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 +5128,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 +6234,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 +6299,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 "" @@ -7281,6 +7293,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -11461,6 +11477,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 +12048,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 +12066,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 +12078,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 +12488,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 +12568,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 +12786,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 +12835,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..0d3524786b 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" @@ -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?" @@ -2764,7 +2756,7 @@ msgstr "Converter Para..." #: editor/editor_node.cpp msgid "MeshLibrary..." -msgstr "Bib. de Meshes..." +msgstr "MeshLibrary..." #: editor/editor_node.cpp msgid "TileSet..." @@ -2894,7 +2886,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 +2907,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 "" @@ -3200,7 +3192,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..." @@ -3435,7 +3427,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 +3721,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 +3919,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 +4319,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 +5019,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:" @@ -5176,19 +5165,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 +5183,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 +5322,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 +5422,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 +5431,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 +5484,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 +5597,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 +5985,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 +6030,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 +6050,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 +6066,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 +6152,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 +6168,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 +6189,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 +6225,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 +6302,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 +6366,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 +6523,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 +6563,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 +6815,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." @@ -7004,7 +7016,7 @@ msgstr "Recarregar" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Resave" -msgstr "Reguardar" +msgstr "Guardar novamente" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" @@ -7020,7 +7032,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" @@ -7322,6 +7334,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 +7416,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 +7436,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 +7988,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 +7996,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 +8012,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 +8430,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 +9156,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 +9374,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 +9388,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 +9456,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 "" @@ -10461,7 +10478,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 +10574,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 +10586,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 +10610,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" @@ -10629,11 +10646,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 +10659,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." @@ -10813,7 +10830,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 +11054,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 +11178,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 +11286,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 +11338,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 +11564,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 +11612,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 +11636,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 +11652,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 +12112,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 +12135,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 +12355,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 +12476,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 +12577,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 +12590,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 +12620,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 +12635,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 +12715,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 +12727,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 +12744,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 +12778,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 +12798,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 +12824,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 +12888,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 +12990,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 +13051,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 +13086,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 +13128,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 +13470,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..b20cc35809 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-05 09:20+0000\n" +"Last-Translator: Lucas Castro <castroclucas@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 @@ -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?" @@ -4017,19 +4016,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" @@ -5272,12 +5268,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 +5288,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 +6410,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 +6474,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" @@ -7426,6 +7445,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 +8868,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 +9584,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." @@ -11663,6 +11685,37 @@ 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 +#, fuzzy +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 +12232,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 +12256,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 +12339,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 +12392,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 +12582,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 +12755,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 +12854,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 +12936,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 +13115,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 +13178,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 +13213,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 +13585,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..100afe3cb9 100644 --- a/editor/translations/ro.po +++ b/editor/translations/ro.po @@ -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?" @@ -5179,10 +5171,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 +5195,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 +6350,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 +6418,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ă" @@ -7414,6 +7427,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -11615,6 +11632,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 +12176,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 +12194,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 +12206,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 +12615,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 +12700,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 +12920,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 +12970,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 +13003,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ă" diff --git a/editor/translations/ru.po b/editor/translations/ru.po index c16d7a8e59..61f4d23157 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,12 @@ # 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. 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-01 20:54+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 +105,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-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -2029,10 +2030,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 +2467,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 +2514,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 +2563,10 @@ msgid "Quit" msgstr "Выход" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Да" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Выйти из редактора?" @@ -3994,19 +3987,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" @@ -5244,12 +5234,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 +5253,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 +5727,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 +5767,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 +6371,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 +6435,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 +6739,7 @@ msgstr "ПривÑзка" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Enable Snap" -msgstr "Ðктивировать привÑзку" +msgstr "Включить привÑзку" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Grid" @@ -7395,6 +7408,11 @@ msgid "Yaw" msgstr "Ð Ñ‹Ñкание" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Размер: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "ÐариÑовано обьектов" @@ -11633,6 +11651,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 +12191,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 +12213,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 +12712,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 +12808,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 +13066,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 +13129,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 +13164,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 +13205,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 +13547,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..e7aabd5542 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" @@ -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 "" @@ -4992,8 +4985,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 +4999,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 +6089,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 +6153,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 "" @@ -7099,6 +7110,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -11157,6 +11172,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 +11706,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 +11724,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 +11736,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 +12139,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 +12219,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 +12436,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 +12485,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..c7839822c9 100644 --- a/editor/translations/sk.po +++ b/editor/translations/sk.po @@ -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?" @@ -5137,10 +5127,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 +5151,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 +6262,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 +6327,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 "" @@ -7310,6 +7321,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 "" @@ -11503,6 +11519,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 +12068,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 +12086,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 +12098,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 +12521,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 +12605,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 +12823,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 +12873,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 +12908,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é" diff --git a/editor/translations/sl.po b/editor/translations/sl.po index 4b542f4daa..ee152a25a3 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?" @@ -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?" @@ -5377,10 +5370,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 +5393,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 +6544,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 +6609,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 "" @@ -7613,6 +7627,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -11878,6 +11896,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 +12455,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 +12473,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 +12485,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 +12915,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 +12997,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 +13224,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 +13277,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 +13312,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" diff --git a/editor/translations/sq.po b/editor/translations/sq.po index ca29161155..90905673c2 100644 --- a/editor/translations/sq.po +++ b/editor/translations/sq.po @@ -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?" @@ -5237,8 +5229,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 +5243,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 +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 "Konverto në %s" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6392,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 "" @@ -7368,6 +7380,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 "" @@ -11497,6 +11514,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 +12055,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 +12073,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 +12085,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 +12490,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 +12572,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 +12789,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 +12838,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 +12871,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..eea195210a 100644 --- a/editor/translations/sr_Cyrl.po +++ b/editor/translations/sr_Cyrl.po @@ -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 "Изађи из уредника?" @@ -5641,8 +5633,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 +5655,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 +6889,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 +6959,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 "Обриши тачку из криве" @@ -8029,6 +8041,11 @@ msgid "Yaw" msgstr "Горе-Доле" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Величина:" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Ðацртани објекти" @@ -13029,6 +13046,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 +13643,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 +13671,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 +13686,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 +14210,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 +14323,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 +14612,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 +14682,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 +14722,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 +15034,6 @@ msgstr "КонÑтанте није могуће мењати." #~ msgstr "Грешка при учитавању реÑурÑа." #, fuzzy -#~ msgid "Done" -#~ msgstr "Готово!" - -#, fuzzy #~ msgid "Failed to create C# project." #~ msgstr "Грешка при учитавању реÑурÑа." diff --git a/editor/translations/sr_Latn.po b/editor/translations/sr_Latn.po index 1a4dcff362..9a88a06a25 100644 --- a/editor/translations/sr_Latn.po +++ b/editor/translations/sr_Latn.po @@ -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 "" @@ -5016,8 +5008,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 +5022,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 +6119,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 +6184,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 "" @@ -7142,6 +7153,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -11246,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 "" @@ -11754,11 +11797,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 +11815,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 +11827,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 +12230,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 +12310,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 +12527,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 +12576,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..9f812d7b8f 100644 --- a/editor/translations/sv.po +++ b/editor/translations/sv.po @@ -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?" @@ -5295,8 +5287,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 +5301,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 +6434,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 +6499,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 "" @@ -7503,6 +7515,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -11774,6 +11790,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 +12340,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 +12358,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 +12370,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 +12799,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 +12888,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 +13113,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 +13162,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 +13198,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 +13395,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..b933fe6052 100644 --- a/editor/translations/ta.po +++ b/editor/translations/ta.po @@ -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 "" @@ -5001,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 @@ -5016,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" @@ -6081,6 +6091,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 +6155,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 "" @@ -7104,6 +7114,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -11162,6 +11176,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 +11705,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 +11723,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 +11735,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 +12138,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 +12218,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 +12435,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 +12484,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..e0ec4b5534 100644 --- a/editor/translations/te.po +++ b/editor/translations/te.po @@ -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 "" @@ -4956,8 +4948,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 +4962,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 +6039,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 +6103,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 "" @@ -7049,6 +7059,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -11077,6 +11091,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 +11614,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 +11632,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 +11644,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 +12047,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 +12127,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 +12344,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 +12393,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..8e083aef79 100644 --- a/editor/translations/th.po +++ b/editor/translations/th.po @@ -12,8 +12,8 @@ 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: Kongfa Warorot <gongpha@hotmail.com>\n" +"PO-Revision-Date: 2020-12-31 07:09+0000\n" +"Last-Translator: Thanachart Monpassorn <nunf_2539@hotmail.com>\n" "Language-Team: Thai <https://hosted.weblate.org/projects/godot-engine/godot/" "th/>\n" "Language: 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.4.1-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -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 "à¸à¸à¸à¹‚ปรà¹à¸à¸£à¸¡?" @@ -3838,19 +3830,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" @@ -5074,10 +5063,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 +5083,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 +6184,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 +6249,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 "ลบจุดในเส้นโค้ง" @@ -7203,6 +7213,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 "à¸à¸à¸šà¹€à¸ˆà¸à¸•์ที่วาด" @@ -11370,6 +11385,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 +11916,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 +11935,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 +11949,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 +12395,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 +12487,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 +12732,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 +12790,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 +12823,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 +12862,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 +13179,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..71379593fd 100644 --- a/editor/translations/tr.po +++ b/editor/translations/tr.po @@ -55,12 +55,13 @@ # 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. 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-01-22 10:21+0000\n" +"Last-Translator: ÇaÄŸlar KOPARIR <ckoparir@gmail.com>\n" "Language-Team: Turkish <https://hosted.weblate.org/projects/godot-engine/" "godot/tr/>\n" "Language: tr\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-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 @@ -1994,10 +1995,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" @@ -2433,6 +2430,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 +2477,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 +2526,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?" @@ -3959,19 +3952,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 dosyada %d eÅŸleÅŸme." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d file." -msgstr "%d eÅŸleÅŸme." +msgstr "%d dosyada %d eÅŸleÅŸme." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d files." -msgstr "%d eÅŸleÅŸme." +msgstr "%d dosyada %d eÅŸleÅŸme." #: editor/groups_editor.cpp msgid "Add to Group" @@ -5211,12 +5201,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 +5221,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 +6337,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 +6401,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" @@ -7360,6 +7371,11 @@ msgid "Yaw" msgstr "Yalpala" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Boyut: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "ÇizilmiÅŸ Nesneler" @@ -11588,6 +11604,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 +12142,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 +12165,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 +12662,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 +12759,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 +13023,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 mini haritasını etkinleÅŸtir." #: scene/gui/popup.cpp msgid "" @@ -13022,6 +13085,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 +13120,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 +13161,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 +13488,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..ef86476e21 100644 --- a/editor/translations/tzm.po +++ b/editor/translations/tzm.po @@ -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 "" @@ -4954,8 +4946,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 +4960,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 +6037,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 +6101,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 "" @@ -7047,6 +7057,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -11074,6 +11088,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 +11611,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 +11629,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 +11641,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 +12044,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 +12124,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 +12341,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 +12390,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..31aa7794a7 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-01-16 01:29+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-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -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 "Вийти з редактора?" @@ -3936,19 +3928,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" @@ -5191,12 +5180,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 +5200,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 +6321,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 +6385,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 "Видалити точку з кривої" @@ -7348,6 +7360,11 @@ msgid "Yaw" msgstr "ВідхиленнÑ" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Розмір: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Ðамальовано об'єктів" @@ -11593,6 +11610,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 +12152,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 +12175,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 +12692,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 +12790,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 +13053,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 +13117,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 +13152,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 +13193,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 +13540,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..bf95b4c01f 100644 --- a/editor/translations/ur_PK.po +++ b/editor/translations/ur_PK.po @@ -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 "" @@ -5058,8 +5050,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 +5064,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 +6171,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 +6236,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 "" @@ -7206,6 +7218,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -11356,6 +11372,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 +11915,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 +11933,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 +11945,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 +12349,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 +12429,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 +12646,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 +12695,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..c08fca86dd 100644 --- a/editor/translations/vi.po +++ b/editor/translations/vi.po @@ -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?" @@ -5176,8 +5168,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 +5182,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 +6304,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 +6370,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 "" @@ -7354,6 +7366,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 "" @@ -11593,6 +11610,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 +12152,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 +12172,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 +12184,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 +12603,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 +12683,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 +12902,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 +12957,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 +12991,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..938981d022 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. @@ -73,11 +73,13 @@ # godhidden <z2zz2zz@yahoo.com>, 2020. # BinotaLIU <me@binota.org>, 2020. # TakWolf <takwolf@foxmail.com>, 2020. +# twoBornottwoB <305766341@qq.com>, 2021. +# Magian <magian1127@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-01-27 23:21+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 +88,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-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -1987,10 +1989,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 +2411,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 +2458,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 +2507,10 @@ msgid "Quit" msgstr "退出" #: editor/editor_node.cpp +msgid "Yes" +msgstr "是" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "确定è¦é€€å‡ºç¼–辑器å—?" @@ -3780,7 +3774,7 @@ msgstr "全部折å " #: editor/filesystem_dock.cpp msgid "Duplicate..." -msgstr "é‡å¤..." +msgstr "å¤åˆ¶ä¸º..." #: editor/filesystem_dock.cpp msgid "Move to Trash" @@ -3893,19 +3887,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" @@ -5131,8 +5122,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 +5139,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" @@ -6230,6 +6239,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 +6303,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 "从曲线ä¸ç§»é™¤é¡¶ç‚¹" @@ -7256,6 +7265,11 @@ msgid "Yaw" msgstr "å航角" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "大å°ï¼š " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "绘制对象" @@ -11413,6 +11427,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 +11954,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 +11972,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 +12426,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 +12515,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 +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 "" @@ -12761,6 +12822,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 +12855,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 +12894,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 +13227,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..70487c165e 100644 --- a/editor/translations/zh_HK.po +++ b/editor/translations/zh_HK.po @@ -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 "è¦é›¢é–‹ç·¨è¼¯å™¨å—Ž?" @@ -5345,8 +5337,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 +5351,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 +6480,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 +6545,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 "" @@ -7557,6 +7569,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -11852,6 +11868,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 +12427,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 +12445,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 +12457,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 +12875,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 +12957,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 +13178,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 +13228,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 +13262,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/zh_TW.po b/editor/translations/zh_TW.po index 59b7ce53fa..1dbca29941 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-01-27 23:21+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-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -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 "è¦çµæŸç·¨è¼¯å™¨å—Žï¼Ÿ" @@ -3847,19 +3839,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" @@ -5085,12 +5074,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 +5091,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 +6192,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 +6256,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 "自曲線ä¸åˆªé™¤æŽ§åˆ¶é»ž" @@ -7211,6 +7218,11 @@ msgid "Yaw" msgstr "å航" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "大å°ï¼š " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "繪製的物件" @@ -11368,6 +11380,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 +11906,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 +11924,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 +12383,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 +12471,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 +12720,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 +12779,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 +12812,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 +12851,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..d70f0eb291 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -171,6 +171,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 +265,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 +294,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,26 +311,26 @@ 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 ("); + 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(", "); @@ -339,42 +341,44 @@ void Main::print_help(const char *p_binary) { #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 +392,6 @@ Error Main::test_setup() { engine = memnew(Engine); - ClassDB::init(); - register_core_types(); register_core_driver_types(); @@ -507,8 +509,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,8 +516,6 @@ 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); @@ -880,7 +878,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 +1008,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") { @@ -1469,9 +1469,11 @@ 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 */ @@ -1578,6 +1580,10 @@ Error Main::setup2(Thread::ID p_main_tid_override) { 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 */ @@ -1628,7 +1634,7 @@ 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)); RenderingServer::get_singleton()->set_default_clear_color(clear); @@ -1684,7 +1690,6 @@ 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("application/config/icon", String()); ProjectSettings::get_singleton()->set_custom_property_info("application/config/icon", @@ -1722,7 +1727,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 +1782,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()) { @@ -2146,11 +2149,6 @@ 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 @@ -2194,22 +2192,6 @@ 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); @@ -2686,8 +2668,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/misc/dist/html/editor.html b/misc/dist/html/editor.html index 18c759ace8..540ab94e51 100644 --- a/misc/dist/html/editor.html +++ b/misc/dist/html/editor.html @@ -4,9 +4,17 @@ <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> + <title>Godot Engine Web Editor ($GODOT_VERSION)</title> <style type='text/css'> + *:focus { + /* More visible outline for better keyboard navigation. */ + outline: 0.125rem solid hsl(220, 100%, 62.5%); + /* Make the outline always appear above other elements. */ + /* Otherwise, one of its sides can be hidden by tabs in the Download and More layouts. */ + position: relative; + } + body { touch-action: none; font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; @@ -18,6 +26,20 @@ overflow: hidden; } + a { + color: hsl(205, 100%, 75%); + text-decoration-color: hsla(205, 100%, 75%, 0.3); + text-decoration-thickness: 0.125rem; + } + + a:hover { + filter: brightness(117.5%); + } + + a:active { + filter: brightness(82.5%); + } + #canvas, #gameCanvas { display: block; margin: 0; @@ -45,10 +67,6 @@ margin: 0 0.5rem; } - .btn:focus { - outline: 1px solid #699ce8; - } - .btn:not(:disabled):hover { color: #e0e1e5; border-color: #666c7b; @@ -171,8 +189,17 @@ <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 /> +<a href="demo.zip">(Try this for example)</a> + <br /> + <br /> <button id="startButton" class="btn" style="margin-bottom: 4rem">Start Godot editor</button> <br /> <button class="btn" onclick="clearPersistence()">Clear persistent data</button> @@ -299,7 +326,7 @@ 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'); @@ -466,11 +493,11 @@ engine.setUnloadAfterInit(false); // Don't want to reload when starting game. engine.init('godot.tools').then(function() { if (zip) { - engine.copyToFS("/home/web_user/preload.zip", zip); + engine.copyToFS("/tmp/preload.zip", zip); } try { // Avoid user creating project in the persistent root folder. - engine.copyToFS("/home/web_user/projects/keep", new Uint8Array()); + engine.copyToFS("/home/web_user/keep", new Uint8Array()); } catch(e) { // File exists } 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/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/hooks/pre-commit-clang-format b/misc/hooks/pre-commit-clang-format index 4e1fbdeb20..6467efe22e 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)" 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/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.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.h b/modules/arkit/arkit_session_delegate.h deleted file mode 100644 index f227d50b35..0000000000 --- a/modules/arkit/arkit_session_delegate.h +++ /dev/null @@ -1,50 +0,0 @@ -/*************************************************************************/ -/* arkit_session_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. */ -/*************************************************************************/ - -#ifndef ARKIT_SESSION_DELEGATE_H -#define ARKIT_SESSION_DELEGATE_H - -#import <ARKit/ARKit.h> -#import <UIKit/UIKit.h> - -class ARKitInterface; - -@interface ARKitSessionDelegate : NSObject <ARSessionDelegate> { - ARKitInterface *arkit_interface; -} - -@property(nonatomic) ARKitInterface *arkit_interface; - -- (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 - -#endif /* !ARKIT_SESSION_DELEGATE_H */ 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..9144a781a0 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); @@ -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..f2740c9c75 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 */ @@ -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/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.h b/modules/bullet/soft_body_bullet.h index b15b72daf9..564566d8b8 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; 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.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.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..82d3ac8b1b 100644 --- a/modules/csg/csg_shape.cpp +++ b/modules/csg/csg_shape.cpp @@ -625,15 +625,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 +918,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; @@ -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)); @@ -1508,8 +1501,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 +1511,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); @@ -1891,8 +1884,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)); 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..dbd6d9e9f9 100644 --- a/modules/cvtt/image_compress_cvtt.cpp +++ b/modules/cvtt/image_compress_cvtt.cpp @@ -37,26 +37,26 @@ #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; + uint32_t current_task = 0; }; static void _digest_row_task(const CVTTCompressionJobParams &p_job_params, const CVTTCompressionRowTask &p_row_task) { @@ -267,12 +267,13 @@ void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::UsedChann 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..5415fcc92e 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] = { diff --git a/modules/enet/doc_classes/NetworkedMultiplayerENet.xml b/modules/enet/doc_classes/NetworkedMultiplayerENet.xml index f46ef2d812..6c713fa1ce 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> diff --git a/modules/enet/networked_multiplayer_enet.cpp b/modules/enet/networked_multiplayer_enet.cpp index 66db9ab84e..91984b8928 100644 --- a/modules/enet/networked_multiplayer_enet.cpp +++ b/modules/enet/networked_multiplayer_enet.cpp @@ -866,28 +866,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..eb70d71c2c 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(); diff --git a/modules/etc/texture_loader_pkm.cpp b/modules/etc/texture_loader_pkm.cpp index b0ea109f76..456473672d 100644 --- a/modules/etc/texture_loader_pkm.cpp +++ b/modules/etc/texture_loader_pkm.cpp @@ -35,11 +35,11 @@ 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) { 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 d84a7ab17c..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) { @@ -135,26 +135,6 @@ EditorSceneImporterMeshNode3D *FBXMeshData::create_fbx_mesh(const ImportState &s &collect_all, HashMap<int, Vector3>()); - // List<int> keys; - // normals.get_key_list(&keys); - // - // const std::vector<Assimp::FBX::MeshGeometry::Edge>& edges = mesh_geometry->get_edge_map(); - // for (int index = 0; index < keys.size(); index++) { - // const int key = keys[index]; - // const int v1 = edges[key].vertex_0; - // const int v2 = edges[key].vertex_1; - // const Vector3& n1 = normals.get(v1); - // const Vector3& n2 = normals.get(v2); - // print_verbose("[" + itos(v1) + "] n1: " + n1 + "\n[" + itos(v2) + "] n2: " + n2); - // //print_verbose("[" + itos(key) + "] n1: " + n1 + ", n2: " + n2) ; - // //print_verbose("vindex: " + itos(edges[key].vertex_0) + ", vindex2: " + itos(edges[key].vertex_1)); - // //Vector3 ver1 = vertices[edges[key].vertex_0]; - // //Vector3 ver2 = vertices[edges[key].vertex_1]; - // /*real_t angle1 = Math::rad2deg(n1.angle_to(n2)); - // real_t angle2 = Math::rad2deg(n2.angle_to(n1)); - // print_verbose("angle of normals: " + rtos(angle1) + " angle 2" + rtos(angle2));*/ - // } - HashMap<int, Vector2> uvs_0; HashMap<int, HashMap<int, Vector2>> uvs_0_raw = extract_per_vertex_data( vertices.size(), @@ -371,6 +351,9 @@ EditorSceneImporterMeshNode3D *FBXMeshData::create_fbx_mesh(const ImportState &s normals_ptr[vertex]); } + if (state.is_blender_fbx) { + morph_st->generate_normals(); + } morph_st->generate_tangents(); surface->morphs.push_back(morph_st->commit_to_arrays()); } @@ -393,6 +376,9 @@ EditorSceneImporterMeshNode3D *FBXMeshData::create_fbx_mesh(const ImportState &s for (const SurfaceId *surface_id = surfaces.next(nullptr); surface_id != nullptr; surface_id = surfaces.next(surface_id)) { SurfaceData *surface = surfaces.getptr(*surface_id); + if (state.is_blender_fbx) { + surface->surface_tool->generate_normals(); + } // you can't generate them without a valid uv map. if (uvs_0_raw.size() > 0) { surface->surface_tool->generate_tangents(); @@ -785,7 +771,7 @@ void FBXMeshData::add_vertex( const Vector3 &p_morph_normal) { ERR_FAIL_INDEX_MSG(p_vertex, (Vertex)p_vertices_position.size(), "FBX file is corrupted, the position of the vertex can't be retrieved."); - if (p_normals.has(p_vertex)) { + if (p_normals.has(p_vertex) && !state.is_blender_fbx) { p_surface_tool->set_normal(p_normals[p_vertex] + p_morph_normal); } @@ -944,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/import_state.h b/modules/fbx/data/import_state.h index 1d664a5212..83bc43faff 100644 --- a/modules/fbx/data/import_state.h +++ b/modules/fbx/data/import_state.h @@ -64,6 +64,7 @@ struct FBXSkeleton; struct ImportState { bool enable_material_import = true; bool enable_animation_import = true; + bool is_blender_fbx = false; Map<StringName, Ref<Texture>> cached_image_searches; Map<uint64_t, Ref<Material>> cached_materials; 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/fbx/doc_classes/EditorSceneImporterFBX.xml b/modules/fbx/doc_classes/EditorSceneImporterFBX.xml index 72b6e0f5fd..da1a68c27c 100644 --- a/modules/fbx/doc_classes/EditorSceneImporterFBX.xml +++ b/modules/fbx/doc_classes/EditorSceneImporterFBX.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="EditorSceneImporterFBX" inherits="EditorSceneImporter" version="3.2"> +<class name="EditorSceneImporterFBX" inherits="EditorSceneImporter" version="4.0"> <brief_description> FBX 3D asset importer. </brief_description> diff --git a/modules/fbx/editor_scene_importer_fbx.cpp b/modules/fbx/editor_scene_importer_fbx.cpp index 5918f4dbed..6576147b2b 100644 --- a/modules/fbx/editor_scene_importer_fbx.cpp +++ b/modules/fbx/editor_scene_importer_fbx.cpp @@ -180,10 +180,12 @@ Node3D *EditorSceneImporterFBX::import_scene(const String &p_path, uint32_t p_fl } if (is_blender_fbx) { - WARN_PRINT("Blender FBX files will not work properly with keyframes or skeletons until we make fixes. Please stand by."); + WARN_PRINT("We don't officially support Blender FBX animations yet, due to issues with upstream Blender,\n" + "so please wait for us to work around remaining issues. We will continue to import the file but it may be broken.\n" + "For minimal breakage, please export FBX from Blender with -Z forward, and Y up."); } - Node3D *spatial = _generate_scene(p_path, &doc, p_flags, p_bake_fps, 8); + Node3D *spatial = _generate_scene(p_path, &doc, p_flags, p_bake_fps, 8, is_blender_fbx); // todo: move to document shutdown (will need to be validated after moving; this code has been validated already) for (FBXDocParser::TokenPtr token : tokens) { if (token) { @@ -327,8 +329,10 @@ Node3D *EditorSceneImporterFBX::_generate_scene( const FBXDocParser::Document *p_document, const uint32_t p_flags, int p_bake_fps, - const int32_t p_max_bone_weights) { + const int32_t p_max_bone_weights, + bool p_is_blender_fbx) { ImportState state; + state.is_blender_fbx = p_is_blender_fbx; state.path = p_path; state.animation_player = NULL; diff --git a/modules/fbx/editor_scene_importer_fbx.h b/modules/fbx/editor_scene_importer_fbx.h index 25c7c1a907..39f8648b0f 100644 --- a/modules/fbx/editor_scene_importer_fbx.h +++ b/modules/fbx/editor_scene_importer_fbx.h @@ -114,7 +114,9 @@ private: Node3D *_generate_scene(const String &p_path, const FBXDocParser::Document *p_document, const uint32_t p_flags, - int p_bake_fps, const int32_t p_max_bone_weights); + int p_bake_fps, + const int32_t p_max_bone_weights, + bool p_is_blender_fbx); template <class T> T _interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, float p_time, AssetImportAnimation::Interpolation p_interp); 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.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/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..87a8c8e376 100644 --- a/modules/gdnative/gdnative/array.cpp +++ b/modules/gdnative/gdnative/array.cpp @@ -33,369 +33,20 @@ #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_min(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->min(); - return v; -} - -void GDAPI godot_array_shuffle(godot_array *p_self) { - Array *self = (Array *)p_self; - self->shuffle(); -} - #ifdef __cplusplus } #endif diff --git a/modules/gdnative/gdnative/basis.cpp b/modules/gdnative/gdnative/basis.cpp index bfcd9bbf2c..86a6d6216c 100644 --- a/modules/gdnative/gdnative/basis.cpp +++ b/modules/gdnative/gdnative/basis.cpp @@ -31,266 +31,15 @@ #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_set_axis_angle_scale(godot_basis *p_self, const godot_vector3 *p_axis, godot_real p_phi, const godot_vector3 *p_scale) { - 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; -} - -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 Basis *self = (const Basis *)p_self; - const Basis *b = (const Basis *)p_b; - *dest = self->slerp(*b, p_t); - return raw_dest; +void GDAPI godot_basis_new(godot_basis *p_self) { + memnew_placement(p_self, Basis); } #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..784c8d439e 100644 --- a/modules/gdnative/gdnative/color.cpp +++ b/modules/gdnative/gdnative/color.cpp @@ -31,178 +31,15 @@ #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 godot_color_set_b(godot_color *p_self, const godot_real val) { - 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; -} - -godot_bool GDAPI godot_color_operator_less(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; +void GDAPI godot_color_new(godot_color *p_self) { + memnew_placement(p_self, Color); } #ifdef __cplusplus diff --git a/modules/gdnative/gdnative/dictionary.cpp b/modules/gdnative/gdnative/dictionary.cpp index f3c040428a..d58e08f4b0 100644 --- a/modules/gdnative/gdnative/dictionary.cpp +++ b/modules/gdnative/gdnative/dictionary.cpp @@ -30,26 +30,16 @@ #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" +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,135 +47,6 @@ 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); -} - -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; -} - #ifdef __cplusplus } #endif diff --git a/modules/gdnative/gdnative/gdnative.cpp b/modules/gdnative/gdnative/gdnative.cpp index 1c11130d89..c3d25f81c7 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,18 +127,6 @@ void GDAPI godot_free(void *p_ptr) { memfree(p_ptr); } -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 _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) { String message = "Error loading GDNative file "; GDNativeLibrary *library = (GDNativeLibrary *)p_library; 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..9e4c6e6f38 100644 --- a/modules/gdnative/gdnative/packed_arrays.cpp +++ b/modules/gdnative/gdnative/packed_arrays.cpp @@ -30,882 +30,103 @@ #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>); -} - -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)); -} - -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(); -} - -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(); + ((PackedInt32Array *)p_self)->~PackedInt32Array(); } // 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(); -} - -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); -} - -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); -} - -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(); -} - -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(); + ((PackedInt64Array *)p_self)->~PackedInt64Array(); } // 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(); -} - -void GDAPI godot_packed_float32_array_invert(godot_packed_float32_array *p_self) { - Vector<float> *self = (Vector<float> *)p_self; - self->invert(); -} - -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); -} - -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(); -} - -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(); + ((PackedFloat32Array *)p_self)->~PackedFloat32Array(); } // 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(); -} - -double GDAPI *godot_packed_float64_array_ptrw(godot_packed_float64_array *p_self) { - Vector<double> *self = (Vector<double> *)p_self; - return self->ptrw(); -} - -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); -} - -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(); -} - -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(); + ((PackedFloat64Array *)p_self)->~PackedFloat64Array(); } // 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); -} - -void GDAPI godot_packed_string_array_sort(godot_packed_string_array *p_self) { - Vector<String> *self = (Vector<String> *)p_self; - self->sort(); -} - -void GDAPI godot_packed_string_array_invert(godot_packed_string_array *p_self) { - Vector<String> *self = (Vector<String> *)p_self; - self->invert(); -} - -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(); -} - -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(); + ((PackedStringArray *)p_self)->~PackedStringArray(); } // 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]); - } -} - -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_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(); -} - -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(); -} - -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(); + ((PackedVector2Array *)p_self)->~PackedVector2Array(); } // 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); -} - -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_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(); -} - -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); -} - -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_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_set(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; - self->set(p_idx, s); -} - -godot_vector2i GDAPI godot_packed_vector2i_array_get(const godot_packed_vector2i_array *p_self, const godot_int p_idx) { - 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_new(godot_packed_vector2i_array *p_self) { + memnew_placement(p_self, Vector<Vector2i>); } void GDAPI godot_packed_vector2i_array_destroy(godot_packed_vector2i_array *p_self) { @@ -914,226 +135,32 @@ void GDAPI godot_packed_vector2i_array_destroy(godot_packed_vector2i_array *p_se // 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(); + ((PackedVector3Array *)p_self)->~PackedVector3Array(); } -// 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>); -} - -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>); +// vector3i - dest->resize(a->size()); - for (int i = 0; i < a->size(); i++) { - dest->set(i, (*a)[i]); - } +void GDAPI godot_packed_vector3i_array_new(godot_packed_vector3i_array *p_self) { + memnew_placement(p_self, Vector<Vector3i>); } -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(); +void GDAPI godot_packed_vector3i_array_destroy(godot_packed_vector3i_array *p_self) { + ((Vector<Vector3i> *)p_self)->~Vector(); } -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); -} - -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); -} - -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_color_array_sort(godot_packed_color_array *p_self) { - Vector<Color> *self = (Vector<Color> *)p_self; - self->sort(); -} - -void GDAPI godot_packed_color_array_invert(godot_packed_color_array *p_self) { - Vector<Color> *self = (Vector<Color> *)p_self; - self->invert(); -} - -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); -} - -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; -} - -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(); -} +// color -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(); +void GDAPI godot_packed_color_array_new(godot_packed_color_array *p_self) { + memnew_placement(p_self, PackedColorArray); } void GDAPI godot_packed_color_array_destroy(godot_packed_color_array *p_self) { - ((Vector<Color> *)p_self)->~Vector(); + ((PackedColorArray *)p_self)->~PackedColorArray(); } #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..87f1d7d8e5 100644 --- a/modules/gdnative/gdnative/quat.cpp +++ b/modules/gdnative/gdnative/quat.cpp @@ -31,205 +31,15 @@ #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_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) { - 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); -} - -godot_vector3 GDAPI godot_quat_xform(const godot_quat *p_self, const godot_vector3 *p_v) { - godot_vector3 dest; - 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); +void GDAPI godot_quat_new(godot_quat *p_self) { + memnew_placement(p_self, Quat); } #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 f704d6c169..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(size_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..e2c933f1ea 100644 --- a/modules/gdnative/gdnative/transform2d.cpp +++ b/modules/gdnative/gdnative/transform2d.cpp @@ -31,179 +31,15 @@ #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; -} - -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_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 Transform2D *self = (const Transform2D *)p_self; - const Rect2 *v = (const Rect2 *)p_v; - *dest = self->xform_inv(*v); - return raw_dest; +void GDAPI godot_transform2d_new(godot_transform2d *p_self) { + memnew_placement(p_self, Transform2D); } #ifdef __cplusplus diff --git a/modules/gdnative/gdnative/variant.cpp b/modules/gdnative/gdnative/variant.cpp index 7ee5fe59e2..79f5a536e5 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; - String *method = (String *)p_method; + 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; + 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; +} + +/// 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; + Variant *iter = (Variant *)r_iter; + + return self->iter_init(*iter, *r_valid); } -uint32_t GDAPI godot_variant_hash(const godot_variant *p_self) { +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; - return self->hash(); + 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,487 @@ 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_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..e2f957e4f2 100644 --- a/modules/gdnative/gdnative/vector2.cpp +++ b/modules/gdnative/gdnative/vector2.cpp @@ -31,430 +31,20 @@ #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; -} - -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_set_x(godot_vector2 *p_self, const godot_real p_x) { - Vector2 *self = (Vector2 *)p_self; - self->x = p_x; -} - -void GDAPI godot_vector2_set_y(godot_vector2 *p_self, const godot_real p_y) { - Vector2 *self = (Vector2 *)p_self; - self->y = p_y; -} - -godot_real GDAPI godot_vector2_get_x(const godot_vector2 *p_self) { - 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; -} - -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) { - Vector2i *self = (Vector2i *)p_self; - self->y = p_y; -} +#ifdef __cplusplus +extern "C" { +#endif -godot_int GDAPI godot_vector2i_get_x(const godot_vector2i *p_self) { - const Vector2i *self = (const Vector2i *)p_self; - return self->x; +void GDAPI godot_vector2_new(godot_vector2 *p_self) { + memnew_placement(p_self, Vector2); } -godot_int GDAPI godot_vector2i_get_y(const godot_vector2i *p_self) { - const Vector2i *self = (const Vector2i *)p_self; - return self->y; +void GDAPI godot_vector2i_new(godot_vector2i *p_self) { + memnew_placement(p_self, Vector2i); } #ifdef __cplusplus diff --git a/modules/gdnative/gdnative/vector3.cpp b/modules/gdnative/gdnative/vector3.cpp index 75aeb59c87..ee365edaec 100644 --- a/modules/gdnative/gdnative/vector3.cpp +++ b/modules/gdnative/gdnative/vector3.cpp @@ -30,433 +30,21 @@ #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; -} - -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; -} - -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_vector3_set_axis(godot_vector3 *p_self, const godot_vector3_axis p_axis, const godot_real p_val) { - Vector3 *self = (Vector3 *)p_self; - self->set_axis(p_axis, p_val); -} - -godot_real GDAPI godot_vector3_get_axis(const godot_vector3 *p_self, const godot_vector3_axis p_axis) { - 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; -} +#ifdef __cplusplus +extern "C" { +#endif -void GDAPI godot_vector3i_set_axis(godot_vector3i *p_self, const godot_vector3_axis p_axis, const godot_int p_val) { - Vector3i *self = (Vector3i *)p_self; - self->set_axis(p_axis, p_val); +void GDAPI godot_vector3_new(godot_vector3 *p_self) { + memnew_placement(p_self, Vector3); } -godot_int GDAPI godot_vector3i_get_axis(const godot_vector3i *p_self, const godot_vector3_axis p_axis) { - const Vector3i *self = (const Vector3i *)p_self; - return self->get_axis(p_axis); +void GDAPI godot_vector3i_new(godot_vector3i *p_self) { + memnew_placement(p_self, Vector3i); } #ifdef __cplusplus diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json index e104c77eae..909e91393e 100644 --- a/modules/gdnative/gdnative_api.json +++ b/modules/gdnative/gdnative_api.json @@ -1,8074 +1,4535 @@ { - "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": [ - ["size_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_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_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_basis_new", + "return_type": "void", + "arguments": [ + [ + "godot_basis *", + "p_self" + ] + ] + }, + { + "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_dictionary_new", + "return_type": "void", + "arguments": [ + [ + "godot_dictionary *", + "p_self" + ] + ] + }, + { + "name": "godot_dictionary_destroy", + "return_type": "void", + "arguments": [ + [ + "godot_dictionary *", + "p_self" + ] + ] + }, + { + "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_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_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_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_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_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_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_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_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_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_plane_new", + "return_type": "void", + "arguments": [ + [ + "godot_plane *", + "p_self" + ] + ] + }, + { + "name": "godot_quat_new", + "return_type": "void", + "arguments": [ + [ + "godot_quat *", + "p_self" + ] + ] + }, + { + "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_vector2_new", + "return_type": "void", + "arguments": [ + [ + "godot_vector2 *", + "r_dest" + ] + ] + }, + { + "name": "godot_vector2i_new", + "return_type": "void", + "arguments": [ + [ + "godot_vector2i *", + "r_dest" + ] + ] + }, + { + "name": "godot_vector3_new", + "return_type": "void", + "arguments": [ + [ + "godot_vector3 *", + "r_dest" + ] + ] + }, + { + "name": "godot_vector3i_new", + "return_type": "void", + "arguments": [ + [ + "godot_vector3i *", + "r_dest" + ] + ] + } + ] + }, + "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.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..d734d49232 100644 --- a/modules/gdnative/include/gdnative/array.h +++ b/modules/gdnative/include/gdnative/array.h @@ -46,103 +46,11 @@ 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> -#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); - #ifdef __cplusplus } #endif diff --git a/modules/gdnative/include/gdnative/basis.h b/modules/gdnative/include/gdnative/basis.h index c6dab4c3c1..d40ca3d6a5 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,9 @@ 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); #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..12c4a829bd 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,9 @@ 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); #ifdef __cplusplus } diff --git a/modules/gdnative/include/gdnative/dictionary.h b/modules/gdnative/include/gdnative/dictionary.h index 3f664567d8..231d2ef578 100644 --- a/modules/gdnative/include/gdnative/dictionary.h +++ b/modules/gdnative/include/gdnative/dictionary.h @@ -46,62 +46,11 @@ 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 -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..630966b035 100644 --- a/modules/gdnative/include/gdnative/gdnative.h +++ b/modules/gdnative/include/gdnative/gdnative.h @@ -118,21 +118,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 +200,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,13 +266,6 @@ 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 -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? - //tags used for safe dynamic casting void GDAPI *godot_get_class_tag(const godot_string_name *p_class); godot_object GDAPI *godot_object_cast_to(const godot_object *p_object, void *p_class_tag); @@ -301,4 +279,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/core/os/rw_lock.cpp b/modules/gdnative/include/gdnative/math_defs.h index 26db0aab30..b5cf389506 100644 --- a/core/os/rw_lock.cpp +++ b/modules/gdnative/include/gdnative/math_defs.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rw_lock.cpp */ +/* math_defs.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,16 +28,39 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "rw_lock.h" +#ifndef GODOT_GDNATIVE_MATH_DEFS_H +#define GODOT_GDNATIVE_MATH_DEFS_H -#include "core/error/error_macros.h" +#ifdef __cplusplus +extern "C" { +#endif -#include <stddef.h> +#include <stdbool.h> +#include <stdint.h> -RWLock *(*RWLock::create_func)() = nullptr; +////// bool -RWLock *RWLock::create() { - ERR_FAIL_COND_V(!create_func, nullptr); +typedef bool godot_bool; - return create_func(); +#define GODOT_TRUE 1 +#define GODOT_FALSE 0 + +/////// int + +typedef int64_t godot_int; + +/////// 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..1a26d8ed6d 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,380 +158,56 @@ 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); -// 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); -// 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); -// 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); -// 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); -// 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); -// 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); -// 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); -// 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); -// 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); - -godot_int GDAPI godot_packed_color_array_size(const godot_packed_color_array *p_self); - -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); #ifdef __cplusplus 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..a87d0bdbe5 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,9 @@ 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); #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/gamecenter/game_center_module.cpp b/modules/gdnative/include/gdnative/signal.h index 8f6ef291c0..ad84542677 100644 --- a/modules/gamecenter/game_center_module.cpp +++ b/modules/gdnative/include/gdnative/signal.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* game_center_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 "game_center_module.h" +#ifndef GODOT_SIGNAL_H +#define GODOT_SIGNAL_H -#include "core/config/engine.h" +#ifdef __cplusplus +extern "C" { +#endif -#include "game_center.h" +#include <stdint.h> -GameCenter *game_center; +#define GODOT_SIGNAL_SIZE (16) -void register_gamecenter_types() { - game_center = memnew(GameCenter); - Engine::get_singleton()->add_singleton(Engine::Singleton("GameCenter", game_center)); -} +#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_gamecenter_types() { - if (game_center) { - memdelete(game_center); - } +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 8f249792bb..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(size_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..85e3a86972 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,9 @@ 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); #ifdef __cplusplus } diff --git a/modules/gdnative/include/gdnative/variant.h b/modules/gdnative/include/gdnative/variant.h index a50947cb72..82bd030170 100644 --- a/modules/gdnative/include/gdnative/variant.h +++ b/modules/gdnative/include/gdnative/variant.h @@ -35,9 +35,9 @@ extern "C" { #endif -#include <stdint.h> +#include <gdnative/math_defs.h> -#define GODOT_VARIANT_SIZE (16 + sizeof(int64_t)) +#define GODOT_VARIANT_SIZE (sizeof(godot_real_t) * 4 + sizeof(int64_t)) #ifndef GODOT_CORE_API_GODOT_VARIANT_TYPE_DEFINED #define GODOT_CORE_API_GODOT_VARIANT_TYPE_DEFINED @@ -146,10 +146,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 +188,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 +199,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 +221,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 +240,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 +256,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 +274,149 @@ 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_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/modules/gdnative/include/gdnative/vector2.h b/modules/gdnative/include/gdnative/vector2.h index eb146a9232..a21ab304d0 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,10 @@ 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); #ifdef __cplusplus } diff --git a/modules/gdnative/include/gdnative/vector3.h b/modules/gdnative/include/gdnative/vector3.h index e0205c2fc7..354c7555b6 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,10 @@ 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); #ifdef __cplusplus } diff --git a/modules/gdnative/include/text/godot_text.h b/modules/gdnative/include/text/godot_text.h index 9de47edf87..44fac3c190 100644 --- a/modules/gdnative/include/text/godot_text.h +++ b/modules/gdnative/include/text/godot_text.h @@ -175,8 +175,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..2b824938f2 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,34 @@ 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. + 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) { @@ -180,7 +194,7 @@ 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(); for (int i = 0; i < constants_count; ++i) { ConstantAPI constant_api; @@ -195,6 +209,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 +227,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; @@ -402,6 +420,191 @@ 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.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 +624,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 +710,164 @@ 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"("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 +886,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..def020adad 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 @@ -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()->terminate(); + library_gdnatives.erase(G); + } } } #ifndef NO_THREADS diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h index 9d72bf39d1..ea7ced6511 100644 --- a/modules/gdnative/nativescript/nativescript.h +++ b/modules/gdnative/nativescript/nativescript.h @@ -51,8 +51,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 +61,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 +78,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 +86,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 +254,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 +262,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 + volatile bool has_objects_to_register = false; // 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 +279,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 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/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..5284bf26f0 --- /dev/null +++ b/modules/gdnative/tests/test_variant.h @@ -0,0 +1,204 @@ +/*************************************************************************/ +/* 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; + 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..f7a3cb8135 100644 --- a/modules/gdnative/text/text_server_gdnative.cpp +++ b/modules/gdnative/text/text_server_gdnative.cpp @@ -703,12 +703,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/videodecoder/video_stream_gdnative.h b/modules/gdnative/videodecoder/video_stream_gdnative.h index e64cda6602..3db5609952 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; 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/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index d60ed8c60c..9e974b6fdc 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -32,59 +32,6 @@ [/codeblock] </description> </method> - <method name="ColorN"> - <return type="Color"> - </return> - <argument index="0" name="name" type="String"> - </argument> - <argument index="1" name="alpha" type="float" default="1.0"> - </argument> - <description> - Returns a color according to the standardized [code]name[/code] with [code]alpha[/code] ranging from 0 to 1. - [codeblock] - red = ColorN("red", 1) - [/codeblock] - Supported color names are the same as the constants defined in [Color]. - </description> - </method> - <method name="abs"> - <return type="float"> - </return> - <argument index="0" name="s" type="float"> - </argument> - <description> - Returns the absolute value of parameter [code]s[/code] (i.e. positive value). - [codeblock] - a = abs(-1) # a is 1 - [/codeblock] - </description> - </method> - <method name="acos"> - <return type="float"> - </return> - <argument index="0" name="s" type="float"> - </argument> - <description> - Returns the arc cosine of [code]s[/code] in radians. Use to get the angle of cosine [code]s[/code]. - [codeblock] - # c is 0.523599 or 30 degrees if converted with rad2deg(s) - c = acos(0.866025) - [/codeblock] - </description> - </method> - <method name="asin"> - <return type="float"> - </return> - <argument index="0" name="s" type="float"> - </argument> - <description> - Returns the arc sine of [code]s[/code] in radians. Use to get the angle of sine [code]s[/code]. - [codeblock] - # s is 0.523599 or 30 degrees if converted with rad2deg(s) - s = asin(0.5) - [/codeblock] - </description> - </method> <method name="assert"> <return type="void"> </return> @@ -93,7 +40,7 @@ <argument index="1" name="message" type="String" default=""""> </argument> <description> - Asserts that the [code]condition[/code] is [code]true[/code]. If the [code]condition[/code] is [code]false[/code], an error is generated. When running from the editor, the running project will also be paused until you resume it. This can be used as a stronger form of [method push_error] for reporting errors to project developers or add-on users. + Asserts that the [code]condition[/code] is [code]true[/code]. If the [code]condition[/code] is [code]false[/code], an error is generated. When running from the editor, the running project will also be paused until you resume it. This can be used as a stronger form of [method @GlobalScope.push_error] for reporting errors to project developers or add-on users. [b]Note:[/b] For performance reasons, the code inside [method assert] is only executed in debug builds or when running the project from the editor. Don't include code that has side effects in an [method assert] call. Otherwise, the project will behave differently when exported in release mode. The optional [code]message[/code] argument, if given, is shown in addition to the generic "Assertion failed" message. You can use this to provide additional details about why the assertion failed. [codeblock] @@ -106,75 +53,10 @@ [/codeblock] </description> </method> - <method name="atan"> - <return type="float"> - </return> - <argument index="0" name="s" type="float"> - </argument> - <description> - Returns the arc tangent of [code]s[/code] in radians. Use it to get the angle from an angle's tangent in trigonometry: [code]atan(tan(angle)) == angle[/code]. - The method cannot know in which quadrant the angle should fall. See [method atan2] if you have both [code]y[/code] and [code]x[/code]. - [codeblock] - a = atan(0.5) # a is 0.463648 - [/codeblock] - </description> - </method> - <method name="atan2"> - <return type="float"> - </return> - <argument index="0" name="y" type="float"> - </argument> - <argument index="1" name="x" type="float"> - </argument> - <description> - Returns the arc tangent of [code]y/x[/code] in radians. Use to get the angle of tangent [code]y/x[/code]. To compute the value, the method takes into account the sign of both arguments in order to determine the quadrant. - Important note: The Y coordinate comes first, by convention. - [codeblock] - a = atan2(0, -1) # a is 3.141593 - [/codeblock] - </description> - </method> - <method name="bytes2var"> - <return type="Variant"> - </return> - <argument index="0" name="bytes" type="PackedByteArray"> - </argument> - <argument index="1" name="allow_objects" type="bool" default="false"> - </argument> - <description> - Decodes a byte array back to a value. When [code]allow_objects[/code] is [code]true[/code] decoding objects is allowed. - [b]WARNING:[/b] Deserialized object can contain code which gets executed. Do not use this option if the serialized object comes from untrusted sources to avoid potential security threats (remote code execution). - </description> - </method> - <method name="cartesian2polar"> - <return type="Vector2"> - </return> - <argument index="0" name="x" type="float"> - </argument> - <argument index="1" name="y" type="float"> - </argument> - <description> - Converts a 2D point expressed in the cartesian coordinate system (X and Y axis) to the polar coordinate system (a distance from the origin and an angle). - </description> - </method> - <method name="ceil"> - <return type="float"> - </return> - <argument index="0" name="s" type="float"> - </argument> - <description> - Rounds [code]s[/code] upward (towards positive infinity), returning the smallest whole number that is not less than [code]s[/code]. - [codeblock] - a = ceil(1.45) # a is 2.0 - a = ceil(1.001) # a is 2.0 - [/codeblock] - See also [method floor], [method round], [method snapped], and [int]. - </description> - </method> <method name="char"> <return type="String"> </return> - <argument index="0" name="code" type="int"> + <argument index="0" name="char" type="int"> </argument> <description> Returns a character as a String of the given Unicode code point (which is compatible with ASCII code). @@ -183,25 +65,6 @@ a = char(65 + 32) # a is "a" a = char(8364) # a is "€" [/codeblock] - This is the inverse of [method ord]. - </description> - </method> - <method name="clamp"> - <return type="float"> - </return> - <argument index="0" name="value" type="float"> - </argument> - <argument index="1" name="min" type="float"> - </argument> - <argument index="2" name="max" type="float"> - </argument> - <description> - Clamps [code]value[/code] and returns a value not less than [code]min[/code] and not more than [code]max[/code]. - [codeblock] - a = clamp(1000, 1, 20) # a is 20 - a = clamp(-10, 1, 20) # a is 1 - a = clamp(15, 1, 20) # a is 15 - [/codeblock] </description> </method> <method name="convert"> @@ -223,159 +86,15 @@ [/codeblock] </description> </method> - <method name="cos"> - <return type="float"> - </return> - <argument index="0" name="s" type="float"> - </argument> - <description> - Returns the cosine of angle [code]s[/code] in radians. - [codeblock] - a = cos(TAU) # a is 1.0 - a = cos(PI) # a is -1.0 - [/codeblock] - </description> - </method> - <method name="cosh"> - <return type="float"> - </return> - <argument index="0" name="s" type="float"> - </argument> - <description> - Returns the hyperbolic cosine of [code]s[/code] in radians. - [codeblock] - print(cosh(1)) # Prints 1.543081 - [/codeblock] - </description> - </method> - <method name="db2linear"> - <return type="float"> - </return> - <argument index="0" name="db" type="float"> - </argument> - <description> - Converts from decibels to linear energy (audio). - </description> - </method> - <method name="dectime"> - <return type="float"> - </return> - <argument index="0" name="value" type="float"> - </argument> - <argument index="1" name="amount" type="float"> - </argument> - <argument index="2" name="step" type="float"> - </argument> - <description> - Returns the result of [code]value[/code] decreased by [code]step[/code] * [code]amount[/code]. - [codeblock] - a = dectime(60, 10, 0.1)) # a is 59.0 - [/codeblock] - </description> - </method> - <method name="deg2rad"> - <return type="float"> - </return> - <argument index="0" name="deg" type="float"> - </argument> - <description> - Converts an angle expressed in degrees to radians. - [codeblock] - r = deg2rad(180) # r is 3.141593 - [/codeblock] - </description> - </method> <method name="dict2inst"> <return type="Object"> </return> - <argument index="0" name="dict" type="Dictionary"> + <argument index="0" name="dictionary" type="Dictionary"> </argument> <description> Converts a dictionary (previously created with [method inst2dict]) back to an instance. Useful for deserializing. </description> </method> - <method name="ease"> - <return type="float"> - </return> - <argument index="0" name="s" type="float"> - </argument> - <argument index="1" name="curve" type="float"> - </argument> - <description> - Easing function, based on exponent. The curve values are: 0 is constant, 1 is linear, 0 to 1 is ease-in, 1+ is ease out. Negative values are in-out/out in. - </description> - </method> - <method name="exp"> - <return type="float"> - </return> - <argument index="0" name="s" type="float"> - </argument> - <description> - The natural exponential function. It raises the mathematical constant [b]e[/b] to the power of [code]s[/code] and returns it. - [b]e[/b] has an approximate value of 2.71828, and can be obtained with [code]exp(1)[/code]. - For exponents to other bases use the method [method pow]. - [codeblock] - a = exp(2) # Approximately 7.39 - [/codeblock] - </description> - </method> - <method name="floor"> - <return type="float"> - </return> - <argument index="0" name="s" type="float"> - </argument> - <description> - Rounds [code]s[/code] downward (towards negative infinity), returning the largest whole number that is not more than [code]s[/code]. - [codeblock] - a = floor(2.45) # a is 2.0 - a = floor(2.99) # a is 2.0 - a = floor(-2.99) # a is -3.0 - [/codeblock] - See also [method ceil], [method round], [method snapped], and [int]. - [b]Note:[/b] This method returns a float. If you need an integer and [code]s[/code] is a non-negative number, you can use [code]int(s)[/code] directly. - </description> - </method> - <method name="fmod"> - <return type="float"> - </return> - <argument index="0" name="a" type="float"> - </argument> - <argument index="1" name="b" type="float"> - </argument> - <description> - Returns the floating-point remainder of [code]a/b[/code], keeping the sign of [code]a[/code]. - [codeblock] - r = fmod(7, 5.5) # r is 1.5 - [/codeblock] - For the integer remainder operation, use the % operator. - </description> - </method> - <method name="fposmod"> - <return type="float"> - </return> - <argument index="0" name="a" type="float"> - </argument> - <argument index="1" name="b" type="float"> - </argument> - <description> - Returns the floating-point modulus of [code]a/b[/code] that wraps equally in positive and negative. - [codeblock] - for i in 7: - var x = 0.5 * i - 1.5 - print("%4.1f %4.1f %4.1f" % [x, fmod(x, 1.5), fposmod(x, 1.5)]) - [/codeblock] - Produces: - [codeblock] - -1.5 -0.0 0.0 - -1.0 -1.0 0.5 - -0.5 -0.5 1.0 - 0.0 0.0 0.0 - 0.5 0.5 0.5 - 1.0 1.0 1.0 - 1.5 0.0 0.0 - [/codeblock] - </description> - </method> <method name="get_stack"> <return type="Array"> </return> @@ -397,22 +116,10 @@ [/codeblock] </description> </method> - <method name="hash"> - <return type="int"> - </return> - <argument index="0" name="var" type="Variant"> - </argument> - <description> - Returns the integer hash of the variable passed. - [codeblock] - print(hash("a")) # Prints 177670 - [/codeblock] - </description> - </method> <method name="inst2dict"> <return type="Dictionary"> </return> - <argument index="0" name="inst" type="Object"> + <argument index="0" name="instance" type="Object"> </argument> <description> Returns the passed instance converted to a dictionary (useful for serializing). @@ -430,92 +137,6 @@ [/codeblock] </description> </method> - <method name="instance_from_id"> - <return type="Object"> - </return> - <argument index="0" name="instance_id" type="int"> - </argument> - <description> - Returns the Object that corresponds to [code]instance_id[/code]. All Objects have a unique instance ID. - [codeblock] - var foo = "bar" - func _ready(): - var id = get_instance_id() - var inst = instance_from_id(id) - print(inst.foo) # Prints bar - [/codeblock] - </description> - </method> - <method name="inverse_lerp"> - <return type="float"> - </return> - <argument index="0" name="from" type="float"> - </argument> - <argument index="1" name="to" type="float"> - </argument> - <argument index="2" name="weight" type="float"> - </argument> - <description> - Returns a normalized value considering the given range. This is the opposite of [method lerp]. - [codeblock] - var middle = lerp(20, 30, 0.75) - # `middle` is now 27.5. - # Now, we pretend to have forgotten the original ratio and want to get it back. - var ratio = inverse_lerp(20, 30, 27.5) - # `ratio` is now 0.75. - [/codeblock] - </description> - </method> - <method name="is_equal_approx"> - <return type="bool"> - </return> - <argument index="0" name="a" type="float"> - </argument> - <argument index="1" name="b" type="float"> - </argument> - <description> - Returns [code]true[/code] if [code]a[/code] and [code]b[/code] are approximately equal to each other. - Here, approximately equal means that [code]a[/code] and [code]b[/code] are within a small internal epsilon of each other, which scales with the magnitude of the numbers. - Infinity values of the same sign are considered equal. - </description> - </method> - <method name="is_inf"> - <return type="bool"> - </return> - <argument index="0" name="s" type="float"> - </argument> - <description> - Returns whether [code]s[/code] is an infinity value (either positive infinity or negative infinity). - </description> - </method> - <method name="is_instance_valid"> - <return type="bool"> - </return> - <argument index="0" name="instance" type="Object"> - </argument> - <description> - Returns whether [code]instance[/code] is a valid object (e.g. has not been deleted from memory). - </description> - </method> - <method name="is_nan"> - <return type="bool"> - </return> - <argument index="0" name="s" type="float"> - </argument> - <description> - Returns whether [code]s[/code] is a NaN ("Not a Number" or invalid) value. - </description> - </method> - <method name="is_zero_approx"> - <return type="bool"> - </return> - <argument index="0" name="s" type="float"> - </argument> - <description> - Returns [code]true[/code] if [code]s[/code] is zero or almost zero. - This method is faster than using [method is_equal_approx] with one value as zero. - </description> - </method> <method name="len"> <return type="int"> </return> @@ -530,63 +151,6 @@ [/codeblock] </description> </method> - <method name="lerp"> - <return type="Variant"> - </return> - <argument index="0" name="from" type="Variant"> - </argument> - <argument index="1" name="to" type="Variant"> - </argument> - <argument index="2" name="weight" type="float"> - </argument> - <description> - Linearly interpolates between two values by a normalized value. This is the opposite of [method inverse_lerp]. - If the [code]from[/code] and [code]to[/code] arguments are of type [int] or [float], the return value is a [float]. - If both are of the same vector type ([Vector2], [Vector3] or [Color]), the return value will be of the same type ([code]lerp[/code] then calls the vector type's [code]lerp[/code] method). - [codeblock] - lerp(0, 4, 0.75) # Returns 3.0 - lerp(Vector2(1, 5), Vector2(3, 2), 0.5) # Returns Vector2(2, 3.5) - [/codeblock] - </description> - </method> - <method name="lerp_angle"> - <return type="float"> - </return> - <argument index="0" name="from" type="float"> - </argument> - <argument index="1" name="to" type="float"> - </argument> - <argument index="2" name="weight" type="float"> - </argument> - <description> - Linearly interpolates between two angles (in radians) by a normalized value. - Similar to [method lerp], but interpolates correctly when the angles wrap around [constant @GDScript.TAU]. - [codeblock] - extends Sprite - var elapsed = 0.0 - func _process(delta): - var min_angle = deg2rad(0.0) - var max_angle = deg2rad(90.0) - rotation = lerp_angle(min_angle, max_angle, elapsed) - elapsed += delta - [/codeblock] - </description> - </method> - <method name="linear2db"> - <return type="float"> - </return> - <argument index="0" name="nrg" type="float"> - </argument> - <description> - Converts from linear energy to decibels (audio). This can be used to implement volume sliders that behave as expected (since volume isn't linear). Example: - [codeblock] - # "Slider" refers to a node that inherits Range such as HSlider or VSlider. - # Its range must be configured to go from 0 to 1. - # Change the bus name if you'd like to change the volume of a specific bus only. - AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Master"), linear2db($Slider.value)) - [/codeblock] - </description> - </method> <method name="load"> <return type="Resource"> </return> @@ -603,172 +167,6 @@ This method is a simplified version of [method ResourceLoader.load], which can be used for more advanced scenarios. </description> </method> - <method name="log"> - <return type="float"> - </return> - <argument index="0" name="s" type="float"> - </argument> - <description> - Natural logarithm. The amount of time needed to reach a certain level of continuous growth. - [b]Note:[/b] This is not the same as the "log" function on most calculators, which uses a base 10 logarithm. - [codeblock] - log(10) # Returns 2.302585 - [/codeblock] - [b]Note:[/b] The logarithm of [code]0[/code] returns [code]-inf[/code], while negative values return [code]-nan[/code]. - </description> - </method> - <method name="max"> - <return type="float"> - </return> - <argument index="0" name="a" type="float"> - </argument> - <argument index="1" name="b" type="float"> - </argument> - <description> - Returns the maximum of two values. - [codeblock] - max(1, 2) # Returns 2 - max(-3.99, -4) # Returns -3.99 - [/codeblock] - </description> - </method> - <method name="min"> - <return type="float"> - </return> - <argument index="0" name="a" type="float"> - </argument> - <argument index="1" name="b" type="float"> - </argument> - <description> - Returns the minimum of two values. - [codeblock] - min(1, 2) # Returns 1 - min(-3.99, -4) # Returns -4 - [/codeblock] - </description> - </method> - <method name="move_toward"> - <return type="float"> - </return> - <argument index="0" name="from" type="float"> - </argument> - <argument index="1" name="to" type="float"> - </argument> - <argument index="2" name="delta" type="float"> - </argument> - <description> - Moves [code]from[/code] toward [code]to[/code] by the [code]delta[/code] value. - Use a negative [code]delta[/code] value to move away. - [codeblock] - move_toward(5, 10, 4) # Returns 9 - move_toward(10, 5, 4) # Returns 6 - move_toward(10, 5, -1.5) # Returns 11.5 - [/codeblock] - </description> - </method> - <method name="nearest_po2"> - <return type="int"> - </return> - <argument index="0" name="value" type="int"> - </argument> - <description> - Returns the nearest equal or larger power of 2 for integer [code]value[/code]. - In other words, returns the smallest value [code]a[/code] where [code]a = pow(2, n)[/code] such that [code]value <= a[/code] for some non-negative integer [code]n[/code]. - [codeblock] - nearest_po2(3) # Returns 4 - nearest_po2(4) # Returns 4 - nearest_po2(5) # Returns 8 - - nearest_po2(0) # Returns 0 (this may not be what you expect) - nearest_po2(-1) # Returns 0 (this may not be what you expect) - [/codeblock] - [b]WARNING:[/b] Due to the way it is implemented, this function returns [code]0[/code] rather than [code]1[/code] for non-positive values of [code]value[/code] (in reality, 1 is the smallest integer power of 2). - </description> - </method> - <method name="ord"> - <return type="int"> - </return> - <argument index="0" name="char" type="String"> - </argument> - <description> - Returns an integer representing the Unicode code point of the given Unicode character [code]char[/code]. - [codeblock] - a = ord("A") # a is 65 - a = ord("a") # a is 97 - a = ord("€") # a is 8364 - [/codeblock] - This is the inverse of [method char]. - </description> - </method> - <method name="parse_json"> - <return type="Variant"> - </return> - <argument index="0" name="json" type="String"> - </argument> - <description> - Parse JSON text to a Variant. (Use [method typeof] to check if the Variant's type is what you expect.) - [b]Note:[/b] The JSON specification does not define integer or float types, but only a [i]number[/i] type. Therefore, parsing a JSON text will convert all numerical values to [float] types. - [b]Note:[/b] JSON objects do not preserve key order like Godot dictionaries, thus, you should not rely on keys being in a certain order if a dictionary is constructed from JSON. In contrast, JSON arrays retain the order of their elements: - [codeblock] - var p = JSON.parse('["hello", "world", "!"]') - if typeof(p.result) == TYPE_ARRAY: - print(p.result[0]) # Prints "hello" - else: - push_error("Unexpected results.") - [/codeblock] - See also [JSON] for an alternative way to parse JSON text. - </description> - </method> - <method name="polar2cartesian"> - <return type="Vector2"> - </return> - <argument index="0" name="r" type="float"> - </argument> - <argument index="1" name="th" type="float"> - </argument> - <description> - Converts a 2D point expressed in the polar coordinate system (a distance from the origin [code]r[/code] and an angle [code]th[/code]) to the cartesian coordinate system (X and Y axis). - </description> - </method> - <method name="posmod"> - <return type="int"> - </return> - <argument index="0" name="a" type="int"> - </argument> - <argument index="1" name="b" type="int"> - </argument> - <description> - Returns the integer modulus of [code]a/b[/code] that wraps equally in positive and negative. - [codeblock] - for i in range(-3, 4): - print("%2d %2d %2d" % [i, i % 3, posmod(i, 3)]) - [/codeblock] - Produces: - [codeblock] - -3 0 0 - -2 -2 1 - -1 -1 2 - 0 0 0 - 1 1 1 - 2 2 2 - 3 0 0 - [/codeblock] - </description> - </method> - <method name="pow"> - <return type="float"> - </return> - <argument index="0" name="base" type="float"> - </argument> - <argument index="1" name="exp" type="float"> - </argument> - <description> - Returns the result of [code]base[/code] raised to the power of [code]exp[/code]. - [codeblock] - pow(2, 5) # Returns 32.0 - [/codeblock] - </description> - </method> <method name="preload"> <return type="Resource"> </return> @@ -783,23 +181,11 @@ [/codeblock] </description> </method> - <method name="print" qualifiers="vararg"> - <return type="void"> - </return> - <description> - Converts one or more arguments to strings in the best way possible and prints them to the console. - [codeblock] - a = [1, 2, 3] - print("a", "=", a) # Prints a=[1, 2, 3] - [/codeblock] - [b]Note:[/b] Consider using [method push_error] and [method push_warning] to print error and warning messages instead of [method print]. This distinguishes them from print messages used for debugging purposes, while also displaying a stack trace when an error or warning is printed. - </description> - </method> <method name="print_debug" qualifiers="vararg"> <return type="void"> </return> <description> - Like [method print], but prints only when used in debug mode. + Like [method @GlobalScope.print], but prints only when used in debug mode. </description> </method> <method name="print_stack"> @@ -813,158 +199,6 @@ [/codeblock] </description> </method> - <method name="printerr" qualifiers="vararg"> - <return type="void"> - </return> - <description> - Prints one or more arguments to strings in the best way possible to standard error line. - [codeblock] - printerr("prints to stderr") - [/codeblock] - </description> - </method> - <method name="printraw" qualifiers="vararg"> - <return type="void"> - </return> - <description> - Prints one or more arguments to strings in the best way possible to console. No newline is added at the end. - [codeblock] - printraw("A") - printraw("B") - # Prints AB - [/codeblock] - [b]Note:[/b] Due to limitations with Godot's built-in console, this only prints to the terminal. If you need to print in the editor, use another method, such as [method print]. - </description> - </method> - <method name="prints" qualifiers="vararg"> - <return type="void"> - </return> - <description> - Prints one or more arguments to the console with a space between each argument. - [codeblock] - prints("A", "B", "C") # Prints A B C - [/codeblock] - </description> - </method> - <method name="printt" qualifiers="vararg"> - <return type="void"> - </return> - <description> - Prints one or more arguments to the console with a tab between each argument. - [codeblock] - printt("A", "B", "C") # Prints A B C - [/codeblock] - </description> - </method> - <method name="push_error"> - <return type="void"> - </return> - <argument index="0" name="message" type="String"> - </argument> - <description> - Pushes an error message to Godot's built-in debugger and to the OS terminal. - [codeblock] - push_error("test error") # Prints "test error" to debugger and terminal as error call - [/codeblock] - [b]Note:[/b] Errors printed this way will not pause project execution. To print an error message and pause project execution in debug builds, use [code]assert(false, "test error")[/code] instead. - </description> - </method> - <method name="push_warning"> - <return type="void"> - </return> - <argument index="0" name="message" type="String"> - </argument> - <description> - Pushes a warning message to Godot's built-in debugger and to the OS terminal. - [codeblock] - push_warning("test warning") # Prints "test warning" to debugger and terminal as warning call - [/codeblock] - </description> - </method> - <method name="rad2deg"> - <return type="float"> - </return> - <argument index="0" name="rad" type="float"> - </argument> - <description> - Converts an angle expressed in radians to degrees. - [codeblock] - rad2deg(0.523599) # Returns 30.0 - [/codeblock] - </description> - </method> - <method name="rand_seed"> - <return type="Array"> - </return> - <argument index="0" name="seed" type="int"> - </argument> - <description> - Random from seed: pass a [code]seed[/code], and an array with both number and new seed is returned. "Seed" here refers to the internal state of the pseudo random number generator. The internal state of the current implementation is 64 bits. - </description> - </method> - <method name="randf"> - <return type="float"> - </return> - <description> - Returns a random floating point value on the interval [code][0, 1][/code]. - [codeblock] - randf() # Returns e.g. 0.375671 - [/codeblock] - </description> - </method> - <method name="randf_range"> - <return type="float"> - </return> - <argument index="0" name="from" type="float"> - </argument> - <argument index="1" name="to" type="float"> - </argument> - <description> - Random range, any floating point value between [code]from[/code] and [code]to[/code]. - [codeblock] - prints(randf_range(-10, 10), randf_range(-10, 10)) # Prints e.g. -3.844535 7.45315 - [/codeblock] - </description> - </method> - <method name="randi"> - <return type="int"> - </return> - <description> - Returns a random unsigned 32 bit integer. Use remainder to obtain a random value in the interval [code][0, N - 1][/code] (where N is smaller than 2^32). - [codeblock] - randi() # Returns random integer between 0 and 2^32 - 1 - randi() % 20 # Returns random integer between 0 and 19 - randi() % 100 # Returns random integer between 0 and 99 - randi() % 100 + 1 # Returns random integer between 1 and 100 - [/codeblock] - </description> - </method> - <method name="randi_range"> - <return type="int"> - </return> - <argument index="0" name="from" type="int"> - </argument> - <argument index="1" name="to" type="int"> - </argument> - <description> - Random range, any 32-bit integer value between [code]from[/code] and [code]to[/code] (inclusive). If [code]to[/code] is lesser than [code]from[/code] they are swapped. - [codeblock] - print(randi_range(0, 1)) # Prints 0 or 1 - print(randi_range(-10, 1000)) # Prints any number from -10 to 1000 - [/codeblock] - </description> - </method> - <method name="randomize"> - <return type="void"> - </return> - <description> - Randomizes the seed (or the internal state) of the random number generator. Current implementation reseeds using a number based on time. - [codeblock] - func _ready(): - randomize() - [/codeblock] - </description> - </method> <method name="range" qualifiers="vararg"> <return type="Array"> </return> @@ -983,157 +217,6 @@ [/codeblock] </description> </method> - <method name="range_lerp"> - <return type="float"> - </return> - <argument index="0" name="value" type="float"> - </argument> - <argument index="1" name="istart" type="float"> - </argument> - <argument index="2" name="istop" type="float"> - </argument> - <argument index="3" name="ostart" type="float"> - </argument> - <argument index="4" name="ostop" type="float"> - </argument> - <description> - Maps a [code]value[/code] from range [code][istart, istop][/code] to [code][ostart, ostop][/code]. - [codeblock] - range_lerp(75, 0, 100, -1, 1) # Returns 0.5 - [/codeblock] - </description> - </method> - <method name="round"> - <return type="float"> - </return> - <argument index="0" name="s" type="float"> - </argument> - <description> - Rounds [code]s[/code] to the nearest whole number, with halfway cases rounded away from zero. - [codeblock] - a = round(2.49) # a is 2.0 - a = round(2.5) # a is 3.0 - a = round(2.51) # a is 3.0 - [/codeblock] - See also [method floor], [method ceil], [method snapped], and [int]. - </description> - </method> - <method name="seed"> - <return type="void"> - </return> - <argument index="0" name="seed" type="int"> - </argument> - <description> - Sets seed for the random number generator. - [codeblock] - my_seed = "Godot Rocks" - seed(my_seed.hash()) - [/codeblock] - </description> - </method> - <method name="sign"> - <return type="float"> - </return> - <argument index="0" name="s" type="float"> - </argument> - <description> - Returns the sign of [code]s[/code]: -1 or 1. Returns 0 if [code]s[/code] is 0. - [codeblock] - sign(-6) # Returns -1 - sign(0) # Returns 0 - sign(6) # Returns 1 - [/codeblock] - </description> - </method> - <method name="sin"> - <return type="float"> - </return> - <argument index="0" name="s" type="float"> - </argument> - <description> - Returns the sine of angle [code]s[/code] in radians. - [codeblock] - sin(0.523599) # Returns 0.5 - [/codeblock] - </description> - </method> - <method name="sinh"> - <return type="float"> - </return> - <argument index="0" name="s" type="float"> - </argument> - <description> - Returns the hyperbolic sine of [code]s[/code]. - [codeblock] - a = log(2.0) # Returns 0.693147 - sinh(a) # Returns 0.75 - [/codeblock] - </description> - </method> - <method name="smoothstep"> - <return type="float"> - </return> - <argument index="0" name="from" type="float"> - </argument> - <argument index="1" name="to" type="float"> - </argument> - <argument index="2" name="s" type="float"> - </argument> - <description> - Returns the result of smoothly interpolating the value of [code]s[/code] between [code]0[/code] and [code]1[/code], based on the where [code]s[/code] lies with respect to the edges [code]from[/code] and [code]to[/code]. - The return value is [code]0[/code] if [code]s <= from[/code], and [code]1[/code] if [code]s >= to[/code]. If [code]s[/code] lies between [code]from[/code] and [code]to[/code], the returned value follows an S-shaped curve that maps [code]s[/code] between [code]0[/code] and [code]1[/code]. - This S-shaped curve is the cubic Hermite interpolator, given by [code]f(s) = 3*s^2 - 2*s^3[/code]. - [codeblock] - smoothstep(0, 2, -5.0) # Returns 0.0 - smoothstep(0, 2, 0.5) # Returns 0.15625 - smoothstep(0, 2, 1.0) # Returns 0.5 - smoothstep(0, 2, 2.0) # Returns 1.0 - [/codeblock] - </description> - </method> - <method name="sqrt"> - <return type="float"> - </return> - <argument index="0" name="s" type="float"> - </argument> - <description> - Returns the square root of [code]s[/code], where [code]s[/code] is a non-negative number. - [codeblock] - sqrt(9) # Returns 3 - [/codeblock] - [b]Note:[/b]Negative values of [code]s[/code] return NaN. If you need negative inputs, use [code]System.Numerics.Complex[/code] in C#. - </description> - </method> - <method name="step_decimals"> - <return type="int"> - </return> - <argument index="0" name="step" type="float"> - </argument> - <description> - Returns the position of the first non-zero digit, after the decimal point. Note that the maximum return value is 10, which is a design decision in the implementation. - [codeblock] - n = step_decimals(5) # n is 0 - n = step_decimals(1.0005) # n is 4 - n = step_decimals(0.000000005) # n is 9 - [/codeblock] - </description> - </method> - <method name="snapped"> - <return type="float"> - </return> - <argument index="0" name="s" type="float"> - </argument> - <argument index="1" name="step" type="float"> - </argument> - <description> - Snaps float value [code]s[/code] to a given [code]step[/code]. This can also be used to round a floating point number to an arbitrary number of decimals. - [codeblock] - snapped(100, 32) # Returns 96.0 - snapped(3.14159, 0.01) # Returns 3.14 - [/codeblock] - See also [method ceil], [method floor], [method round], and [int]. - </description> - </method> <method name="str" qualifiers="vararg"> <return type="String"> </return> @@ -1147,200 +230,12 @@ [/codeblock] </description> </method> - <method name="str2var"> - <return type="Variant"> - </return> - <argument index="0" name="string" type="String"> - </argument> - <description> - Converts a formatted string that was returned by [method var2str] to the original value. - [codeblock] - a = '{ "a": 1, "b": 2 }' - b = str2var(a) - print(b["a"]) # Prints 1 - [/codeblock] - </description> - </method> - <method name="tan"> - <return type="float"> - </return> - <argument index="0" name="s" type="float"> - </argument> - <description> - Returns the tangent of angle [code]s[/code] in radians. - [codeblock] - tan(deg2rad(45)) # Returns 1 - [/codeblock] - </description> - </method> - <method name="tanh"> - <return type="float"> - </return> - <argument index="0" name="s" type="float"> - </argument> - <description> - Returns the hyperbolic tangent of [code]s[/code]. - [codeblock] - a = log(2.0) # a is 0.693147 - b = tanh(a) # b is 0.6 - [/codeblock] - </description> - </method> - <method name="to_json"> - <return type="String"> - </return> - <argument index="0" name="var" type="Variant"> - </argument> - <description> - Converts a [Variant] [code]var[/code] to JSON text and return the result. Useful for serializing data to store or send over the network. - [codeblock] - # Both numbers below are integers. - a = { "a": 1, "b": 2 } - b = to_json(a) - print(b) # {"a":1, "b":2} - # Both numbers above are floats, even if they display without any decimal places. - [/codeblock] - [b]Note:[/b] The JSON specification does not define integer or float types, but only a [i]number[/i] type. Therefore, converting a [Variant] to JSON text will convert all numerical values to [float] types. - See also [JSON] for an alternative way to convert a [Variant] to JSON text. - </description> - </method> <method name="type_exists"> <return type="bool"> </return> - <argument index="0" name="type" type="String"> - </argument> - <description> - Returns whether the given class exists in [ClassDB]. - [codeblock] - type_exists("Sprite2D") # Returns true - type_exists("Variant") # Returns false - [/codeblock] - </description> - </method> - <method name="typeof"> - <return type="int"> - </return> - <argument index="0" name="what" type="Variant"> - </argument> - <description> - Returns the internal type of the given Variant object, using the [enum Variant.Type] values. - [codeblock] - p = parse_json('["a", "b", "c"]') - if typeof(p) == TYPE_ARRAY: - print(p[0]) # Prints a - else: - print("unexpected results") - [/codeblock] - </description> - </method> - <method name="validate_json"> - <return type="String"> - </return> - <argument index="0" name="json" type="String"> - </argument> - <description> - Checks that [code]json[/code] is valid JSON data. Returns an empty string if valid, or an error message otherwise. - [codeblock] - j = to_json([1, 2, 3]) - v = validate_json(j) - if not v: - print("Valid JSON.") - else: - push_error("Invalid JSON: " + v) - [/codeblock] - </description> - </method> - <method name="var2bytes"> - <return type="PackedByteArray"> - </return> - <argument index="0" name="var" type="Variant"> - </argument> - <argument index="1" name="full_objects" type="bool" default="false"> - </argument> - <description> - Encodes a variable value to a byte array. When [code]full_objects[/code] is [code]true[/code] encoding objects is allowed (and can potentially include code). - </description> - </method> - <method name="var2str"> - <return type="String"> - </return> - <argument index="0" name="var" type="Variant"> - </argument> - <description> - Converts a Variant [code]var[/code] to a formatted string that can later be parsed using [method str2var]. - [codeblock] - a = { "a": 1, "b": 2 } - print(var2str(a)) - [/codeblock] - prints - [codeblock] - { - "a": 1, - "b": 2 - } - [/codeblock] - </description> - </method> - <method name="weakref"> - <return type="WeakRef"> - </return> - <argument index="0" name="obj" type="Object"> - </argument> - <description> - Returns a weak reference to an object. - A weak reference to an object is not enough to keep the object alive: when the only remaining references to a referent are weak references, garbage collection is free to destroy the referent and reuse its memory for something else. However, until the object is actually destroyed the weak reference may return the object even if there are no strong references to it. - </description> - </method> - <method name="wrapf"> - <return type="float"> - </return> - <argument index="0" name="value" type="float"> - </argument> - <argument index="1" name="min" type="float"> - </argument> - <argument index="2" name="max" type="float"> + <argument index="0" name="type" type="StringName"> </argument> <description> - Wraps float [code]value[/code] between [code]min[/code] and [code]max[/code]. - Usable for creating loop-alike behavior or infinite surfaces. - [codeblock] - # Infinite loop between 5.0 and 9.9 - value = wrapf(value + 0.1, 5.0, 10.0) - [/codeblock] - [codeblock] - # Infinite rotation (in radians) - angle = wrapf(angle + 0.1, 0.0, TAU) - [/codeblock] - [codeblock] - # Infinite rotation (in radians) - angle = wrapf(angle + 0.1, -PI, PI) - [/codeblock] - [b]Note:[/b] If [code]min[/code] is [code]0[/code], this is equivalent to [method fposmod], so prefer using that instead. - [code]wrapf[/code] is more flexible than using the [method fposmod] approach by giving the user control over the minimum value. - </description> - </method> - <method name="wrapi"> - <return type="int"> - </return> - <argument index="0" name="value" type="int"> - </argument> - <argument index="1" name="min" type="int"> - </argument> - <argument index="2" name="max" type="int"> - </argument> - <description> - Wraps integer [code]value[/code] between [code]min[/code] and [code]max[/code]. - Usable for creating loop-alike behavior or infinite surfaces. - [codeblock] - # Infinite loop between 5 and 9 - frame = wrapi(frame + 1, 5, 10) - [/codeblock] - [codeblock] - # result is -2 - var result = wrapi(-6, -5, -1) - [/codeblock] - [b]Note:[/b] If [code]min[/code] is [code]0[/code], this is equivalent to [method posmod], so prefer using that instead. - [code]wrapi[/code] is more flexible than using the [method posmod] approach by giving the user control over the minimum value. </description> </method> </methods> 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.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..f891145988 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); diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 37f01b2571..ee270f6b2f 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; 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..b491440d4c 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -494,9 +494,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_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..96744a15d7 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. 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 2b6211095a..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]; } @@ -2918,21 +2926,30 @@ Error GLTFDocument::_parse_images(Ref<GLTFState> state, const String &p_base_pat } } else { // Relative path to an external image file. uri = p_base_path.plus_file(uri).replace("\\", "/"); // Fix for Windows. - // The spec says that if mimeType is defined, we should enforce it. - // So we should only rely on ResourceLoader::load if mimeType is not defined, - // otherwise we should use the same logic as for buffers. - if (mimetype == "image/png" || mimetype == "image/jpeg") { - // Load data buffer and rely on PNG and JPEG-specific logic below to load the image. - // This makes it possible to load a file with a wrong extension but correct MIME type, - // e.g. "foo.jpg" containing PNG data and with MIME type "image/png". ResourceLoader would fail. + // ResourceLoader will rely on the file extension to use the relevant loader. + // The spec says that if mimeType is defined, it should take precedence (e.g. + // there could be a `.png` image which is actually JPEG), but there's no easy + // API for that in Godot, so we'd have to load as a buffer (i.e. embedded in + // the material), so we do this only as fallback. + Ref<Texture2D> texture = ResourceLoader::load(uri); + if (texture.is_valid()) { + state->images.push_back(texture); + continue; + } else if (mimetype == "image/png" || mimetype == "image/jpeg") { + // Fallback to loading as byte array. + // This enables us to support the spec's requirement that we honor mimetype + // regardless of file URI. data = FileAccess::get_file_as_array(uri); - ERR_FAIL_COND_V_MSG(data.size() == 0, ERR_PARSE_ERROR, "glTF: Couldn't load image file as an array: " + uri); + if (data.size() == 0) { + WARN_PRINT(vformat("glTF: Image index '%d' couldn't be loaded as a buffer of MIME type '%s' from URI: %s. Skipping it.", i, mimetype, uri)); + state->images.push_back(Ref<Texture2D>()); // Placeholder to keep count. + continue; + } data_ptr = data.ptr(); data_size = data.size(); } else { - // Good old ResourceLoader will rely on file extension. - Ref<Texture2D> texture = ResourceLoader::load(uri); - state->images.push_back(texture); + WARN_PRINT(vformat("glTF: Image index '%d' couldn't be loaded from URI: %s. Skipping it.", i, uri)); + state->images.push_back(Ref<Texture2D>()); // Placeholder to keep count. continue; } } @@ -5088,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; @@ -5097,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); @@ -5111,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); @@ -5141,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"); @@ -5167,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) { @@ -5216,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); @@ -5247,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); @@ -5262,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)); @@ -5544,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(); @@ -6015,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; @@ -6274,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/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..134aadb75e 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> diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index 5a17541075..323b025774 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -1046,26 +1046,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..565830c16f 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(); @@ -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.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.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..82aaa492fc 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; @@ -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 56976bd623..eb9d817f99 100644 --- a/modules/lightmapper_rd/lm_compute.glsl +++ b/modules/lightmapper_rd/lm_compute.glsl @@ -249,6 +249,15 @@ float quick_hash(vec2 pos) { return fract(sin(dot(pos * 19.19, vec2(49.5791, 97.413))) * 49831.189237); } +float get_omni_attenuation(float distance, float inv_range, float decay) { + float nd = distance * inv_range; + nd *= nd; + nd *= nd; // nd^4 + nd = max(1.0 - nd, 0.0); + nd *= nd; // nd^2 + return nd * pow(max(distance, 0.0001), -decay); +} + void main() { #ifdef MODE_LIGHT_PROBES int probe_index = int(gl_GlobalInvocationID.x); @@ -300,17 +309,20 @@ void main() { d /= lights.data[i].range; - attenuation = pow(max(1.0 - d, 0.0), lights.data[i].attenuation); + attenuation = get_omni_attenuation(d, 1.0 / lights.data[i].range, lights.data[i].attenuation); 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/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 392a2fb565..8627f71987 100644 --- a/modules/minimp3/audio_stream_mp3.cpp +++ b/modules/minimp3/audio_stream_mp3.cpp @@ -120,7 +120,10 @@ AudioStreamPlaybackMP3::~AudioStreamPlaybackMP3() { Ref<AudioStreamPlayback> AudioStreamMP3::instance_playback() { Ref<AudioStreamPlaybackMP3> mp3s; - ERR_FAIL_COND_V(data == nullptr, mp3s); + ERR_FAIL_COND_V_MSG(data == nullptr, mp3s, + "This AudioStreamMP3 does not have an audio file assigned " + "to it. AudioStreamMP3 should not be created from the " + "inspector or with `.new()`. Instead, load an audio file."); mp3s.instance(); mp3s->mp3_stream = Ref<AudioStreamMP3>(this); 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..bd29dc1876 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; 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..38e403b2e1 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -365,7 +365,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); 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/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/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/OpenSimplexNoise.xml b/modules/opensimplex/doc_classes/OpenSimplexNoise.xml index 9fe4c9c249..dcda5c2324 100644 --- a/modules/opensimplex/doc_classes/OpenSimplexNoise.xml +++ b/modules/opensimplex/doc_classes/OpenSimplexNoise.xml @@ -32,7 +32,7 @@ <argument index="1" name="height" type="int"> </argument> <description> - Generate a noise image with the requested [code]width[/code] and [code]height[/code], based on the current noise parameters. + Generate a noise image in [constant Image.FORMAT_L8] format with the requested [code]width[/code] and [code]height[/code], based on the current noise parameters. </description> </method> <method name="get_noise_1d" qualifiers="const"> @@ -108,7 +108,7 @@ <argument index="0" name="size" type="int"> </argument> <description> - Generate a tileable noise image, based on the current noise parameters. Generated seamless images are always square ([code]size[/code] × [code]size[/code]). + 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]). </description> </method> </methods> diff --git a/modules/opensimplex/noise_texture.cpp b/modules/opensimplex/noise_texture.cpp index 1d75e46747..98381ca144 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; 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 403340e39c..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(); } @@ -104,7 +98,7 @@ void OpenSimplexNoise::set_lacunarity(float p_lacunarity) { Ref<Image> OpenSimplexNoise::get_image(int p_width, int p_height) const { Vector<uint8_t> data; - data.resize(p_width * p_height * 4); + data.resize(p_width * p_height); uint8_t *wd8 = data.ptrw(); @@ -112,21 +106,17 @@ Ref<Image> OpenSimplexNoise::get_image(int p_width, int p_height) const { for (int j = 0; j < p_width; j++) { float v = get_noise_2d(j, i); v = v * 0.5 + 0.5; // Normalize [0..1] - uint8_t value = uint8_t(CLAMP(v * 255.0, 0, 255)); - wd8[(i * p_width + j) * 4 + 0] = value; - wd8[(i * p_width + j) * 4 + 1] = value; - wd8[(i * p_width + j) * 4 + 2] = value; - wd8[(i * p_width + j) * 4 + 3] = 255; + wd8[(i * p_width + j)] = uint8_t(CLAMP(v * 255.0, 0, 255)); } } - Ref<Image> image = memnew(Image(p_width, p_height, false, Image::FORMAT_RGBA8, data)); + Ref<Image> image = memnew(Image(p_width, p_height, false, Image::FORMAT_L8, data)); return image; } Ref<Image> OpenSimplexNoise::get_seamless_image(int p_size) const { Vector<uint8_t> data; - data.resize(p_size * p_size * 4); + data.resize(p_size * p_size); uint8_t *wd8 = data.ptrw(); @@ -135,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); @@ -147,15 +137,11 @@ Ref<Image> OpenSimplexNoise::get_seamless_image(int p_size) const { float v = get_noise_4d(x, y, z, w); v = v * 0.5 + 0.5; // Normalize [0..1] - uint8_t value = uint8_t(CLAMP(v * 255.0, 0, 255)); - wd8[(i * p_size + j) * 4 + 0] = value; - wd8[(i * p_size + j) * 4 + 1] = value; - wd8[(i * p_size + j) * 4 + 2] = value; - wd8[(i * p_size + j) * 4 + 3] = 255; + wd8[(i * p_size + j)] = uint8_t(CLAMP(v * 255.0, 0, 255)); } } - Ref<Image> image = memnew(Image(p_size, p_size, false, Image::FORMAT_RGBA8, data)); + Ref<Image> image = memnew(Image(p_size, p_size, false, Image::FORMAT_L8, data)); return image; } 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..056a923a2d 100644 --- a/modules/pvr/texture_loader_pvr.cpp +++ b/modules/pvr/texture_loader_pvr.cpp @@ -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/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 82d1206e93..f7bf650354 100644 --- a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp +++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp @@ -124,7 +124,10 @@ AudioStreamPlaybackOGGVorbis::~AudioStreamPlaybackOGGVorbis() { Ref<AudioStreamPlayback> AudioStreamOGGVorbis::instance_playback() { Ref<AudioStreamPlaybackOGGVorbis> ovs; - ERR_FAIL_COND_V(data == nullptr, ovs); + ERR_FAIL_COND_V_MSG(data == nullptr, ovs, + "This AudioStreamOGGVorbis does not have an audio file assigned " + "to it. AudioStreamOGGVorbis should not be created from the " + "inspector or with `.new()`. Instead, load an audio file."); ovs.instance(); ovs->vorbis_stream = Ref<AudioStreamOGGVorbis>(this); @@ -260,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/bitmap_font_adv.cpp b/modules/text_server_adv/bitmap_font_adv.cpp index 01fa94aa7c..df771301e6 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(); } @@ -540,7 +540,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/dynamic_font_adv.cpp b/modules/text_server_adv/dynamic_font_adv.cpp index fcefa60d98..5a16158c0f 100644 --- a/modules/text_server_adv/dynamic_font_adv.cpp +++ b/modules/text_server_adv/dynamic_font_adv.cpp @@ -946,7 +946,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 +977,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)) { diff --git a/modules/text_server_adv/dynamic_font_adv.h b/modules/text_server_adv/dynamic_font_adv.h index c35dd9390b..cd538cb8e1 100644 --- a/modules/text_server_adv/dynamic_font_adv.h +++ b/modules/text_server_adv/dynamic_font_adv.h @@ -74,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 { @@ -91,10 +88,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; 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..8e4771685d 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -1602,11 +1602,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 +1624,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 +1635,7 @@ bool TextServerAdvanced::shaped_text_update_breaks(RID p_shaped) { } } ubrk_close(bi); + i++; } sd->sort_valid = false; @@ -1636,7 +1644,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) { diff --git a/modules/text_server_fb/bitmap_font_fb.cpp b/modules/text_server_fb/bitmap_font_fb.cpp index 5c691b7bbd..c9a9cc6eba 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(); } @@ -321,7 +321,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/dynamic_font_fb.cpp b/modules/text_server_fb/dynamic_font_fb.cpp index 4eecba6ae8..df7756cbd0 100644 --- a/modules/text_server_fb/dynamic_font_fb.cpp +++ b/modules/text_server_fb/dynamic_font_fb.cpp @@ -626,7 +626,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 +658,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; diff --git a/modules/text_server_fb/dynamic_font_fb.h b/modules/text_server_fb/dynamic_font_fb.h index f1cd758f2c..81b18f6af3 100644 --- a/modules/text_server_fb/dynamic_font_fb.h +++ b/modules/text_server_fb/dynamic_font_fb.h @@ -70,14 +70,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 +83,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; 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..afe26d4a5f 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 @@ -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 }; diff --git a/modules/theora/video_stream_theora.h b/modules/theora/video_stream_theora.h index d2036b5cb4..71e56e2ee8 100644 --- a/modules/theora/video_stream_theora.h +++ b/modules/theora/video_stream_theora.h @@ -52,12 +52,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 +65,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 +74,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 +110,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; + volatile bool thread_exit = false; static void _streaming_thread(void *ud); #endif - int audio_track; + int audio_track = 0; protected: void clear(); 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/VisualScript.xml b/modules/visual_script/doc_classes/VisualScript.xml index 088d84d2ec..5112ea43a7 100644 --- a/modules/visual_script/doc_classes/VisualScript.xml +++ b/modules/visual_script/doc_classes/VisualScript.xml @@ -26,23 +26,23 @@ </return> <argument index="0" name="name" type="StringName"> </argument> + <argument index="1" name="func_node_id" type="int"> + </argument> <description> - Add a function with the specified name to the VisualScript. + Add a function with the specified name to the VisualScript, and assign the root [VisualScriptFunction] node's id as [code]func_node_id[/code]. </description> </method> <method name="add_node"> <return type="void"> </return> - <argument index="0" name="func" type="StringName"> - </argument> - <argument index="1" name="id" type="int"> + <argument index="0" name="id" type="int"> </argument> - <argument index="2" name="node" type="VisualScriptNode"> + <argument index="1" name="node" type="VisualScriptNode"> </argument> - <argument index="3" name="position" type="Vector2" default="Vector2( 0, 0 )"> + <argument index="2" name="position" type="Vector2" default="Vector2( 0, 0 )"> </argument> <description> - Add a node to a function of the VisualScript. + Add a node to the VisualScript. </description> </method> <method name="add_variable"> @@ -157,15 +157,13 @@ <method name="data_connect"> <return type="void"> </return> - <argument index="0" name="func" type="StringName"> - </argument> - <argument index="1" name="from_node" type="int"> + <argument index="0" name="from_node" type="int"> </argument> - <argument index="2" name="from_port" type="int"> + <argument index="1" name="from_port" type="int"> </argument> - <argument index="3" name="to_node" type="int"> + <argument index="2" name="to_node" type="int"> </argument> - <argument index="4" name="to_port" type="int"> + <argument index="3" name="to_port" type="int"> </argument> <description> Connect two data ports. The value of [code]from_node[/code]'s [code]from_port[/code] would be fed into [code]to_node[/code]'s [code]to_port[/code]. @@ -174,15 +172,13 @@ <method name="data_disconnect"> <return type="void"> </return> - <argument index="0" name="func" type="StringName"> + <argument index="0" name="from_node" type="int"> </argument> - <argument index="1" name="from_node" type="int"> + <argument index="1" name="from_port" type="int"> </argument> - <argument index="2" name="from_port" type="int"> + <argument index="2" name="to_node" type="int"> </argument> - <argument index="3" name="to_node" type="int"> - </argument> - <argument index="4" name="to_port" type="int"> + <argument index="3" name="to_port" type="int"> </argument> <description> Disconnect two data ports previously connected with [method data_connect]. @@ -197,37 +193,31 @@ Returns the id of a function's entry point node. </description> </method> - <method name="get_function_scroll" qualifiers="const"> - <return type="Vector2"> - </return> - <argument index="0" name="name" type="StringName"> - </argument> - <description> - Returns the position of the center of the screen for a given function. - </description> - </method> <method name="get_node" qualifiers="const"> <return type="VisualScriptNode"> </return> - <argument index="0" name="func" type="StringName"> - </argument> - <argument index="1" name="id" type="int"> + <argument index="0" name="id" type="int"> </argument> <description> - Returns a node given its id and its function. + Returns a node given its id. </description> </method> <method name="get_node_position" qualifiers="const"> <return type="Vector2"> </return> - <argument index="0" name="func" type="StringName"> - </argument> - <argument index="1" name="id" type="int"> + <argument index="0" name="id" type="int"> </argument> <description> Returns a node's position in pixels. </description> </method> + <method name="get_scroll" qualifiers="const"> + <return type="Vector2"> + </return> + <description> + Returns the current position of the center of the screen. + </description> + </method> <method name="get_variable_default_value" qualifiers="const"> <return type="Variant"> </return> @@ -267,15 +257,13 @@ <method name="has_data_connection" qualifiers="const"> <return type="bool"> </return> - <argument index="0" name="func" type="StringName"> - </argument> - <argument index="1" name="from_node" type="int"> + <argument index="0" name="from_node" type="int"> </argument> - <argument index="2" name="from_port" type="int"> + <argument index="1" name="from_port" type="int"> </argument> - <argument index="3" name="to_node" type="int"> + <argument index="2" name="to_node" type="int"> </argument> - <argument index="4" name="to_port" type="int"> + <argument index="3" name="to_port" type="int"> </argument> <description> Returns whether the specified data ports are connected. @@ -293,9 +281,7 @@ <method name="has_node" qualifiers="const"> <return type="bool"> </return> - <argument index="0" name="func" type="StringName"> - </argument> - <argument index="1" name="id" type="int"> + <argument index="0" name="id" type="int"> </argument> <description> Returns whether a node exists with the given id. @@ -304,13 +290,11 @@ <method name="has_sequence_connection" qualifiers="const"> <return type="bool"> </return> - <argument index="0" name="func" type="StringName"> - </argument> - <argument index="1" name="from_node" type="int"> + <argument index="0" name="from_node" type="int"> </argument> - <argument index="2" name="from_output" type="int"> + <argument index="1" name="from_output" type="int"> </argument> - <argument index="3" name="to_node" type="int"> + <argument index="2" name="to_node" type="int"> </argument> <description> Returns whether the specified sequence ports are connected. @@ -346,12 +330,10 @@ <method name="remove_node"> <return type="void"> </return> - <argument index="0" name="func" type="StringName"> - </argument> - <argument index="1" name="id" type="int"> + <argument index="0" name="id" type="int"> </argument> <description> - Remove a specific node. + Remove the node with the specified id. </description> </method> <method name="remove_variable"> @@ -399,13 +381,11 @@ <method name="sequence_connect"> <return type="void"> </return> - <argument index="0" name="func" type="StringName"> + <argument index="0" name="from_node" type="int"> </argument> - <argument index="1" name="from_node" type="int"> + <argument index="1" name="from_output" type="int"> </argument> - <argument index="2" name="from_output" type="int"> - </argument> - <argument index="3" name="to_node" type="int"> + <argument index="2" name="to_node" type="int"> </argument> <description> Connect two sequence ports. The execution will flow from of [code]from_node[/code]'s [code]from_output[/code] into [code]to_node[/code]. @@ -415,29 +395,16 @@ <method name="sequence_disconnect"> <return type="void"> </return> - <argument index="0" name="func" type="StringName"> - </argument> - <argument index="1" name="from_node" type="int"> + <argument index="0" name="from_node" type="int"> </argument> - <argument index="2" name="from_output" type="int"> + <argument index="1" name="from_output" type="int"> </argument> - <argument index="3" name="to_node" type="int"> + <argument index="2" name="to_node" type="int"> </argument> <description> Disconnect two sequence ports previously connected with [method sequence_connect]. </description> </method> - <method name="set_function_scroll"> - <return type="void"> - </return> - <argument index="0" name="name" type="StringName"> - </argument> - <argument index="1" name="ofs" type="Vector2"> - </argument> - <description> - Position the center of the screen for a function. - </description> - </method> <method name="set_instance_base_type"> <return type="void"> </return> @@ -450,14 +417,21 @@ <method name="set_node_position"> <return type="void"> </return> - <argument index="0" name="func" type="StringName"> + <argument index="0" name="id" type="int"> </argument> - <argument index="1" name="id" type="int"> + <argument index="1" name="position" type="Vector2"> </argument> - <argument index="2" name="position" type="Vector2"> + <description> + Set the node position in the VisualScript graph. + </description> + </method> + <method name="set_scroll"> + <return type="void"> + </return> + <argument index="0" name="ofs" type="Vector2"> </argument> <description> - Position a node on the screen. + Set the screen center to the given position. </description> </method> <method name="set_variable_default_value"> @@ -496,9 +470,7 @@ </methods> <signals> <signal name="node_ports_changed"> - <argument index="0" name="function" type="String"> - </argument> - <argument index="1" name="id" type="int"> + <argument index="0" name="id" type="int"> </argument> <description> Emitted when the ports of a node are changed. diff --git a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml index 000fbd0140..219ffd01d3 100644 --- a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml +++ b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml @@ -92,7 +92,7 @@ <constant name="MATH_STEP_DECIMALS" value="24" enum="BuiltinFunc"> Return the number of digit places after the decimal that the first non-zero digit occurs. </constant> - <constant name="MATH_STEPIFY" value="25" enum="BuiltinFunc"> + <constant name="MATH_SNAPPED" value="25" enum="BuiltinFunc"> Return the input snapped to a given step. </constant> <constant name="MATH_LERP" value="26" enum="BuiltinFunc"> @@ -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 1ea2a80788..2517b17168 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -36,7 +36,7 @@ #include "scene/main/node.h" #include "visual_script_nodes.h" -//used by editor, this is not really saved +// Used by editor, this is not really saved. void VisualScriptNode::set_breakpoint(bool p_breakpoint) { breakpoint = p_breakpoint; } @@ -55,8 +55,8 @@ void VisualScriptNode::set_default_input_value(int p_port, const Variant &p_valu default_input_values[p_port] = p_value; #ifdef TOOLS_ENABLED - for (Set<VisualScript *>::Element *E = scripts_used.front(); E; E = E->next()) { - E->get()->set_edited(true); + if (script_used.is_valid()) { + script_used->set_edited(true); } #endif } @@ -73,14 +73,14 @@ void VisualScriptNode::_set_default_input_values(Array p_values) { void VisualScriptNode::validate_input_default_values() { default_input_values.resize(MAX(default_input_values.size(), get_input_value_port_count())); //let it grow as big as possible, we don't want to lose values on resize - //actually validate on save + // Actually validate on save. for (int i = 0; i < get_input_value_port_count(); i++) { Variant::Type expected = get_input_value_port_info(i).type; if (expected == Variant::NIL || expected == default_input_values[i].get_type()) { continue; } else { - //not the same, reconvert + // Not the same, reconvert. Callable::CallError ce; Variant existing = default_input_values[i]; const Variant *existingp = &existing; @@ -94,7 +94,7 @@ void VisualScriptNode::validate_input_default_values() { } Array VisualScriptNode::_get_default_input_values() const { - //validate on save, since on load there is little info about this + // Validate on save, since on load there is little info about this. Array values = default_input_values; values.resize(get_input_value_port_count()); @@ -118,6 +118,8 @@ void VisualScriptNode::_bind_methods() { } VisualScriptNode::TypeGuess VisualScriptNode::guess_output_type(TypeGuess *p_inputs, int p_output) const { + ERR_FAIL_COND_V(get_output_value_port_count() <= p_output, TypeGuess()); + PropertyInfo pinfo = get_output_value_port_info(p_output); TypeGuess tg; @@ -131,15 +133,10 @@ VisualScriptNode::TypeGuess VisualScriptNode::guess_output_type(TypeGuess *p_inp } Ref<VisualScript> VisualScriptNode::get_visual_script() const { - if (scripts_used.size()) { - return Ref<VisualScript>(scripts_used.front()->get()); - } - - return Ref<VisualScript>(); + return script_used; } VisualScriptNode::VisualScriptNode() { - breakpoint = false; } //////////////// @@ -147,8 +144,6 @@ VisualScriptNode::VisualScriptNode() { ///////////////////// VisualScriptNodeInstance::VisualScriptNodeInstance() { - sequence_outputs = nullptr; - input_ports = nullptr; } VisualScriptNodeInstance::~VisualScriptNodeInstance() { @@ -165,13 +160,15 @@ VisualScriptNodeInstance::~VisualScriptNodeInstance() { } } -void VisualScript::add_function(const StringName &p_name) { +void VisualScript::add_function(const StringName &p_name, int p_func_node_id) { ERR_FAIL_COND(instances.size()); ERR_FAIL_COND(!String(p_name).is_valid_identifier()); ERR_FAIL_COND(functions.has(p_name)); + ERR_FAIL_COND(variables.has(p_name)); + ERR_FAIL_COND(custom_signals.has(p_name)); functions[p_name] = Function(); - functions[p_name].scroll = Vector2(-50, -100); + functions[p_name].func_id = p_func_node_id; } bool VisualScript::has_function(const StringName &p_name) const { @@ -182,11 +179,7 @@ void VisualScript::remove_function(const StringName &p_name) { ERR_FAIL_COND(instances.size()); ERR_FAIL_COND(!functions.has(p_name)); - for (Map<int, Function::NodeData>::Element *E = functions[p_name].nodes.front(); E; E = E->next()) { - E->get().node->disconnect("ports_changed", callable_mp(this, &VisualScript::_node_ports_changed)); - E->get().node->scripts_used.erase(this); - } - + // Let the editor handle the node removal. functions.erase(p_name); } @@ -207,53 +200,36 @@ void VisualScript::rename_function(const StringName &p_name, const StringName &p functions.erase(p_name); } -void VisualScript::set_function_scroll(const StringName &p_name, const Vector2 &p_scroll) { - ERR_FAIL_COND(!functions.has(p_name)); - functions[p_name].scroll = p_scroll; +void VisualScript::set_scroll(const Vector2 &p_scroll) { + scroll = p_scroll; } -Vector2 VisualScript::get_function_scroll(const StringName &p_name) const { - ERR_FAIL_COND_V(!functions.has(p_name), Vector2()); - return functions[p_name].scroll; +Vector2 VisualScript::get_scroll() const { + return scroll; } void VisualScript::get_function_list(List<StringName> *r_functions) const { - for (const Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) { - r_functions->push_back(E->key()); - } - - r_functions->sort_custom<StringName::AlphCompare>(); + functions.get_key_list(r_functions); + // r_functions->sort_custom<StringName::AlphCompare>(); // Don't force sorting. } int VisualScript::get_function_node_id(const StringName &p_name) const { ERR_FAIL_COND_V(!functions.has(p_name), -1); - return functions[p_name].function_id; + return functions[p_name].func_id; } void VisualScript::_node_ports_changed(int p_id) { - StringName function; - - for (Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) { - if (E->get().nodes.has(p_id)) { - function = E->key(); - break; - } - } - - ERR_FAIL_COND(function == StringName()); - - Function &func = functions[function]; - Ref<VisualScriptNode> vsn = func.nodes[p_id].node; + Ref<VisualScriptNode> vsn = nodes[p_id].node; vsn->validate_input_default_values(); - //must revalidate all the functions + // Must revalidate all the functions. { List<SequenceConnection> to_remove; - for (Set<SequenceConnection>::Element *E = func.sequence_connections.front(); E; E = E->next()) { + for (Set<SequenceConnection>::Element *E = sequence_connections.front(); E; E = E->next()) { if (E->get().from_node == p_id && E->get().from_output >= vsn->get_output_sequence_port_count()) { to_remove.push_back(E->get()); } @@ -263,7 +239,7 @@ void VisualScript::_node_ports_changed(int p_id) { } while (to_remove.size()) { - func.sequence_connections.erase(to_remove.front()->get()); + sequence_connections.erase(to_remove.front()->get()); to_remove.pop_front(); } } @@ -271,7 +247,7 @@ void VisualScript::_node_ports_changed(int p_id) { { List<DataConnection> to_remove; - for (Set<DataConnection>::Element *E = func.data_connections.front(); E; E = E->next()) { + for (Set<DataConnection>::Element *E = data_connections.front(); E; E = E->next()) { if (E->get().from_node == p_id && E->get().from_port >= vsn->get_output_value_port_count()) { to_remove.push_back(E->get()); } @@ -281,63 +257,47 @@ void VisualScript::_node_ports_changed(int p_id) { } while (to_remove.size()) { - func.data_connections.erase(to_remove.front()->get()); + data_connections.erase(to_remove.front()->get()); to_remove.pop_front(); } } #ifdef TOOLS_ENABLED - set_edited(true); //something changed, let's set as edited - emit_signal("node_ports_changed", function, p_id); + set_edited(true); // Something changed, let's set as edited. + emit_signal("node_ports_changed", p_id); #endif } -void VisualScript::add_node(const StringName &p_func, int p_id, const Ref<VisualScriptNode> &p_node, const Point2 &p_pos) { +void VisualScript::add_node(int p_id, const Ref<VisualScriptNode> &p_node, const Point2 &p_pos) { ERR_FAIL_COND(instances.size()); - ERR_FAIL_COND(!functions.has(p_func)); - - for (Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) { - ERR_FAIL_COND(E->get().nodes.has(p_id)); //id can exist only one in script, even for different functions - } + ERR_FAIL_COND(nodes.has(p_id)); // ID can exist only one in script. - Function &func = functions[p_func]; - - if (Object::cast_to<VisualScriptFunction>(*p_node)) { - //the function indeed - ERR_FAIL_COND_MSG(func.function_id >= 0, "A function node has already been set here."); - - func.function_id = p_id; - } - - Function::NodeData nd; + NodeData nd; nd.node = p_node; nd.pos = p_pos; Ref<VisualScriptNode> vsn = p_node; vsn->connect("ports_changed", callable_mp(this, &VisualScript::_node_ports_changed), varray(p_id)); - vsn->scripts_used.insert(this); - vsn->validate_input_default_values(); // Validate when fully loaded + vsn->script_used = Ref<VisualScript>(this); + vsn->validate_input_default_values(); // Validate when fully loaded. - func.nodes[p_id] = nd; + nodes[p_id] = nd; } -void VisualScript::remove_node(const StringName &p_func, int p_id) { +void VisualScript::remove_node(int p_id) { ERR_FAIL_COND(instances.size()); - ERR_FAIL_COND(!functions.has(p_func)); - Function &func = functions[p_func]; - - ERR_FAIL_COND(!func.nodes.has(p_id)); + ERR_FAIL_COND(!nodes.has(p_id)); { List<SequenceConnection> to_remove; - for (Set<SequenceConnection>::Element *E = func.sequence_connections.front(); E; E = E->next()) { + for (Set<SequenceConnection>::Element *E = sequence_connections.front(); E; E = E->next()) { if (E->get().from_node == p_id || E->get().to_node == p_id) { to_remove.push_back(E->get()); } } while (to_remove.size()) { - func.sequence_connections.erase(to_remove.front()->get()); + sequence_connections.erase(to_remove.front()->get()); to_remove.pop_front(); } } @@ -345,122 +305,88 @@ void VisualScript::remove_node(const StringName &p_func, int p_id) { { List<DataConnection> to_remove; - for (Set<DataConnection>::Element *E = func.data_connections.front(); E; E = E->next()) { + for (Set<DataConnection>::Element *E = data_connections.front(); E; E = E->next()) { if (E->get().from_node == p_id || E->get().to_node == p_id) { to_remove.push_back(E->get()); } } while (to_remove.size()) { - func.data_connections.erase(to_remove.front()->get()); + data_connections.erase(to_remove.front()->get()); to_remove.pop_front(); } } - if (Object::cast_to<VisualScriptFunction>(func.nodes[p_id].node.ptr())) { - func.function_id = -1; //revert to invalid - } + nodes[p_id].node->disconnect("ports_changed", callable_mp(this, &VisualScript::_node_ports_changed)); + nodes[p_id].node->script_used.unref(); - func.nodes[p_id].node->disconnect("ports_changed", callable_mp(this, &VisualScript::_node_ports_changed)); - func.nodes[p_id].node->scripts_used.erase(this); - - func.nodes.erase(p_id); + nodes.erase(p_id); } -bool VisualScript::has_node(const StringName &p_func, int p_id) const { - ERR_FAIL_COND_V(!functions.has(p_func), false); - const Function &func = functions[p_func]; - - return func.nodes.has(p_id); +bool VisualScript::has_node(int p_id) const { + return nodes.has(p_id); } -Ref<VisualScriptNode> VisualScript::get_node(const StringName &p_func, int p_id) const { - ERR_FAIL_COND_V(!functions.has(p_func), Ref<VisualScriptNode>()); - const Function &func = functions[p_func]; - - ERR_FAIL_COND_V(!func.nodes.has(p_id), Ref<VisualScriptNode>()); +Ref<VisualScriptNode> VisualScript::get_node(int p_id) const { + ERR_FAIL_COND_V(!nodes.has(p_id), Ref<VisualScriptNode>()); - return func.nodes[p_id].node; + return nodes[p_id].node; } -void VisualScript::set_node_position(const StringName &p_func, int p_id, const Point2 &p_pos) { +void VisualScript::set_node_position(int p_id, const Point2 &p_pos) { ERR_FAIL_COND(instances.size()); - ERR_FAIL_COND(!functions.has(p_func)); - Function &func = functions[p_func]; - - ERR_FAIL_COND(!func.nodes.has(p_id)); - func.nodes[p_id].pos = p_pos; + ERR_FAIL_COND(!nodes.has(p_id)); + nodes[p_id].pos = p_pos; } -Point2 VisualScript::get_node_position(const StringName &p_func, int p_id) const { - ERR_FAIL_COND_V(!functions.has(p_func), Point2()); - const Function &func = functions[p_func]; - - ERR_FAIL_COND_V(!func.nodes.has(p_id), Point2()); - return func.nodes[p_id].pos; +Point2 VisualScript::get_node_position(int p_id) const { + ERR_FAIL_COND_V(!nodes.has(p_id), Point2()); + return nodes[p_id].pos; } -void VisualScript::get_node_list(const StringName &p_func, List<int> *r_nodes) const { - ERR_FAIL_COND(!functions.has(p_func)); - const Function &func = functions[p_func]; - - for (const Map<int, Function::NodeData>::Element *E = func.nodes.front(); E; E = E->next()) { - r_nodes->push_back(E->key()); - } +void VisualScript::get_node_list(List<int> *r_nodes) const { + nodes.get_key_list(r_nodes); } -void VisualScript::sequence_connect(const StringName &p_func, int p_from_node, int p_from_output, int p_to_node) { +void VisualScript::sequence_connect(int p_from_node, int p_from_output, int p_to_node) { ERR_FAIL_COND(instances.size()); - ERR_FAIL_COND(!functions.has(p_func)); - Function &func = functions[p_func]; SequenceConnection sc; sc.from_node = p_from_node; sc.from_output = p_from_output; sc.to_node = p_to_node; - ERR_FAIL_COND(func.sequence_connections.has(sc)); + ERR_FAIL_COND(sequence_connections.has(sc)); - func.sequence_connections.insert(sc); + sequence_connections.insert(sc); } -void VisualScript::sequence_disconnect(const StringName &p_func, int p_from_node, int p_from_output, int p_to_node) { - ERR_FAIL_COND(!functions.has(p_func)); - Function &func = functions[p_func]; - +void VisualScript::sequence_disconnect(int p_from_node, int p_from_output, int p_to_node) { SequenceConnection sc; sc.from_node = p_from_node; sc.from_output = p_from_output; sc.to_node = p_to_node; - ERR_FAIL_COND(!func.sequence_connections.has(sc)); + ERR_FAIL_COND(!sequence_connections.has(sc)); - func.sequence_connections.erase(sc); + sequence_connections.erase(sc); } -bool VisualScript::has_sequence_connection(const StringName &p_func, int p_from_node, int p_from_output, int p_to_node) const { - ERR_FAIL_COND_V(!functions.has(p_func), false); - const Function &func = functions[p_func]; - +bool VisualScript::has_sequence_connection(int p_from_node, int p_from_output, int p_to_node) const { SequenceConnection sc; sc.from_node = p_from_node; sc.from_output = p_from_output; sc.to_node = p_to_node; - return func.sequence_connections.has(sc); + return sequence_connections.has(sc); } -void VisualScript::get_sequence_connection_list(const StringName &p_func, List<SequenceConnection> *r_connection) const { - ERR_FAIL_COND(!functions.has(p_func)); - const Function &func = functions[p_func]; - - for (const Set<SequenceConnection>::Element *E = func.sequence_connections.front(); E; E = E->next()) { +void VisualScript::get_sequence_connection_list(List<SequenceConnection> *r_connection) const { + for (const Set<SequenceConnection>::Element *E = sequence_connections.front(); E; E = E->next()) { r_connection->push_back(E->get()); } } -void VisualScript::data_connect(const StringName &p_func, int p_from_node, int p_from_port, int p_to_node, int p_to_port) { +void VisualScript::data_connect(int p_from_node, int p_from_port, int p_to_node, int p_to_port) { ERR_FAIL_COND(instances.size()); - ERR_FAIL_COND(!functions.has(p_func)); - Function &func = functions[p_func]; DataConnection dc; dc.from_node = p_from_node; @@ -468,72 +394,55 @@ void VisualScript::data_connect(const StringName &p_func, int p_from_node, int p dc.to_node = p_to_node; dc.to_port = p_to_port; - ERR_FAIL_COND(func.data_connections.has(dc)); + ERR_FAIL_COND(data_connections.has(dc)); - func.data_connections.insert(dc); + data_connections.insert(dc); } -void VisualScript::data_disconnect(const StringName &p_func, int p_from_node, int p_from_port, int p_to_node, int p_to_port) { - ERR_FAIL_COND(!functions.has(p_func)); - Function &func = functions[p_func]; - +void VisualScript::data_disconnect(int p_from_node, int p_from_port, int p_to_node, int p_to_port) { DataConnection dc; dc.from_node = p_from_node; dc.from_port = p_from_port; dc.to_node = p_to_node; dc.to_port = p_to_port; - ERR_FAIL_COND(!func.data_connections.has(dc)); + ERR_FAIL_COND(!data_connections.has(dc)); - func.data_connections.erase(dc); + data_connections.erase(dc); } -bool VisualScript::has_data_connection(const StringName &p_func, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const { - ERR_FAIL_COND_V(!functions.has(p_func), false); - const Function &func = functions[p_func]; - +bool VisualScript::has_data_connection(int p_from_node, int p_from_port, int p_to_node, int p_to_port) const { DataConnection dc; dc.from_node = p_from_node; dc.from_port = p_from_port; dc.to_node = p_to_node; dc.to_port = p_to_port; - return func.data_connections.has(dc); + return data_connections.has(dc); } -bool VisualScript::is_input_value_port_connected(const StringName &p_func, int p_node, int p_port) const { - ERR_FAIL_COND_V(!functions.has(p_func), false); - const Function &func = functions[p_func]; - - for (const Set<DataConnection>::Element *E = func.data_connections.front(); E; E = E->next()) { +bool VisualScript::is_input_value_port_connected(int p_node, int p_port) const { + for (const Set<DataConnection>::Element *E = data_connections.front(); E; E = E->next()) { if (E->get().to_node == p_node && E->get().to_port == p_port) { return true; } } - return false; } -bool VisualScript::get_input_value_port_connection_source(const StringName &p_func, int p_node, int p_port, int *r_node, int *r_port) const { - ERR_FAIL_COND_V(!functions.has(p_func), false); - const Function &func = functions[p_func]; - - for (const Set<DataConnection>::Element *E = func.data_connections.front(); E; E = E->next()) { +bool VisualScript::get_input_value_port_connection_source(int p_node, int p_port, int *r_node, int *r_port) const { + for (const Set<DataConnection>::Element *E = data_connections.front(); E; E = E->next()) { if (E->get().to_node == p_node && E->get().to_port == p_port) { *r_node = E->get().from_node; *r_port = E->get().from_port; return true; } } - return false; } -void VisualScript::get_data_connection_list(const StringName &p_func, List<DataConnection> *r_connection) const { - ERR_FAIL_COND(!functions.has(p_func)); - const Function &func = functions[p_func]; - - for (const Set<DataConnection>::Element *E = func.data_connections.front(); E; E = E->next()) { +void VisualScript::get_data_connection_list(List<DataConnection> *r_connection) const { + for (const Set<DataConnection>::Element *E = data_connections.front(); E; E = E->next()) { r_connection->push_back(E->get()); } } @@ -653,11 +562,8 @@ Dictionary VisualScript::_get_variable_info(const StringName &p_name) const { } void VisualScript::get_variable_list(List<StringName> *r_variables) const { - for (Map<StringName, Variable>::Element *E = variables.front(); E; E = E->next()) { - r_variables->push_back(E->key()); - } - - r_variables->sort_custom<StringName::AlphCompare>(); + variables.get_key_list(r_variables); + // r_variables->sort_custom<StringName::AlphCompare>(); // Don't force it. } void VisualScript::set_instance_base_type(const StringName &p_type) { @@ -680,24 +586,19 @@ void VisualScript::rename_variable(const StringName &p_name, const StringName &p variables[p_new_name] = variables[p_name]; variables.erase(p_name); - - List<StringName> funcs; - get_function_list(&funcs); - for (List<StringName>::Element *F = funcs.front(); F; F = F->next()) { // loop through all the functions - List<int> ids; - get_node_list(F->get(), &ids); - for (List<int>::Element *E = ids.front(); E; E = E->next()) { - Ref<VisualScriptVariableGet> nodeget = get_node(F->get(), E->get()); - if (nodeget.is_valid()) { - if (nodeget->get_variable() == p_name) { - nodeget->set_variable(p_new_name); - } - } else { - Ref<VisualScriptVariableSet> nodeset = get_node(F->get(), E->get()); - if (nodeset.is_valid()) { - if (nodeset->get_variable() == p_name) { - nodeset->set_variable(p_new_name); - } + List<int> ids; + get_node_list(&ids); + for (List<int>::Element *E = ids.front(); E; E = E->next()) { + Ref<VisualScriptVariableGet> nodeget = get_node(E->get()); + if (nodeget.is_valid()) { + if (nodeget->get_variable() == p_name) { + nodeget->set_variable(p_new_name); + } + } else { + Ref<VisualScriptVariableSet> nodeset = get_node(E->get()); + if (nodeset.is_valid()) { + if (nodeset->get_variable() == p_name) { + nodeset->set_variable(p_new_name); } } } @@ -808,23 +709,24 @@ void VisualScript::get_custom_signal_list(List<StringName> *r_custom_signals) co } int VisualScript::get_available_id() const { - int max_id = 0; - for (Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) { - if (E->get().nodes.is_empty()) { - continue; + // This is infinitely increasing, + // so one might want to implement a better solution, + // if the there is a case for huge number of nodes to be added to visual script. + List<int> nds; + nodes.get_key_list(&nds); + int max = -1; + for (const List<int>::Element *E = nds.front(); E; E = E->next()) { + if (E->get() > max) { + max = E->get(); } - - int last_id = E->get().nodes.back()->key(); - max_id = MAX(max_id, last_id + 1); } - - return max_id; + return (max + 1); } ///////////////////////////////// bool VisualScript::can_instance() const { - return true; //ScriptServer::is_scripting_enabled(); + return true; // ScriptServer::is_scripting_enabled(); } StringName VisualScript::get_instance_base_type() const { @@ -832,7 +734,7 @@ StringName VisualScript::get_instance_base_type() const { } Ref<Script> VisualScript::get_base_script() const { - return Ref<Script>(); // no inheritance in visual script + return Ref<Script>(); // No inheritance in visual script. } #ifdef TOOLS_ENABLED @@ -842,20 +744,23 @@ void VisualScript::_placeholder_erased(PlaceHolderScriptInstance *p_placeholder) void VisualScript::_update_placeholders() { if (placeholders.size() == 0) { - return; //no bother if no placeholders + return; // No bother if no placeholders. } List<PropertyInfo> pinfo; Map<StringName, Variant> values; - for (Map<StringName, Variable>::Element *E = variables.front(); E; E = E->next()) { - if (!E->get()._export) { + List<StringName> keys; + variables.get_key_list(&keys); + + for (List<StringName>::Element *E = keys.front(); E; E = E->next()) { + if (!variables[E->get()]._export) { continue; } - PropertyInfo p = E->get().info; - p.name = String(E->key()); + PropertyInfo p = variables[E->get()].info; + p.name = String(E->get()); pinfo.push_back(p); - values[p.name] = E->get().default_value; + values[p.name] = variables[E->get()].default_value; } for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) { @@ -875,17 +780,18 @@ ScriptInstance *VisualScript::instance_create(Object *p_this) { List<PropertyInfo> pinfo; Map<StringName, Variant> values; - for (Map<StringName, Variable>::Element *E = variables.front(); E; E = E->next()) { - if (!E->get()._export) { + List<StringName> keys; + variables.get_key_list(&keys); + + for (const List<StringName>::Element *E = keys.front(); E; E = E->next()) { + if (!variables[E->get()]._export) continue; - } - PropertyInfo p = E->get().info; - p.name = String(E->key()); + PropertyInfo p = variables[E->get()].info; + p.name = String(E->get()); pinfo.push_back(p); - values[p.name] = E->get().default_value; + values[p.name] = variables[E->get()].default_value; } - sins->update(pinfo, values); return sins; @@ -928,7 +834,7 @@ bool VisualScript::is_tool() const { } bool VisualScript::is_valid() const { - return true; //always valid + return true; // Always valid. } ScriptLanguage *VisualScript::get_language() const { @@ -964,11 +870,14 @@ bool VisualScript::get_property_default_value(const StringName &p_property, Vari } void VisualScript::get_script_method_list(List<MethodInfo> *p_list) const { - for (Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) { + List<StringName> funcs; + functions.get_key_list(&funcs); + + for (List<StringName>::Element *E = funcs.front(); E; E = E->next()) { MethodInfo mi; - mi.name = E->key(); - if (E->get().function_id >= 0) { - Ref<VisualScriptFunction> func = E->get().nodes[E->get().function_id].node; + mi.name = E->get(); + if (functions[E->get()].func_id >= 0) { + Ref<VisualScriptFunction> func = nodes[functions[E->get()].func_id].node; if (func.is_valid()) { for (int i = 0; i < func->get_argument_count(); i++) { PropertyInfo arg; @@ -988,15 +897,15 @@ bool VisualScript::has_method(const StringName &p_method) const { } MethodInfo VisualScript::get_method_info(const StringName &p_method) const { - const Map<StringName, Function>::Element *E = functions.find(p_method); - if (!E) { + const Function funct = functions[p_method]; + if (funct.func_id == -1) { return MethodInfo(); } MethodInfo mi; - mi.name = E->key(); - if (E->get().function_id >= 0) { - Ref<VisualScriptFunction> func = E->get().nodes[E->get().function_id].node; + mi.name = p_method; + if (funct.func_id >= 0) { + Ref<VisualScriptFunction> func = nodes[funct.func_id].node; if (func.is_valid()) { for (int i = 0; i < func->get_argument_count(); i++) { PropertyInfo arg; @@ -1028,28 +937,18 @@ void VisualScript::get_script_property_list(List<PropertyInfo> *p_list) const { } int VisualScript::get_member_line(const StringName &p_member) const { -#ifdef TOOLS_ENABLED - if (has_function(p_member)) { - for (Map<int, Function::NodeData>::Element *E = functions[p_member].nodes.front(); E; E = E->next()) { - if (Object::cast_to<VisualScriptFunction>(E->get().node.ptr())) { - return E->key(); - } - } - } -#endif - return -1; + return functions[p_member].func_id; // will be -1 if not found } #ifdef TOOLS_ENABLED bool VisualScript::are_subnodes_edited() const { - for (const Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) { - for (const Map<int, Function::NodeData>::Element *F = E->get().nodes.front(); F; F = F->next()) { - if (F->get().node->is_edited()) { - return true; - } + List<int> keys; + nodes.get_key_list(&keys); + for (const List<int>::Element *F = keys.front(); F; F = F->next()) { + if (nodes[F->get()].node->is_edited()) { + return true; } } - return false; } #endif @@ -1140,85 +1039,41 @@ void VisualScript::_set_data(const Dictionary &p_data) { Array funcs = d["functions"]; functions.clear(); - Vector2 last_pos = Vector2(-100 * funcs.size(), -100 * funcs.size()); // this is the center of the last fn box - Vector2 last_size = Vector2(0.0, 0.0); - for (int i = 0; i < funcs.size(); i++) { Dictionary func = funcs[i]; - - StringName name = func["name"]; - //int id=func["function_id"]; - add_function(name); - - set_function_scroll(name, func["scroll"]); - - Array nodes = func["nodes"]; - - if (!d.has("vs_unify") && nodes.size() > 0) { - Vector2 top_left = nodes[1]; - Vector2 bottom_right = nodes[1]; - - for (int j = 0; j < nodes.size(); j += 3) { - Point2 pos = nodes[j + 1]; - if (pos.y > top_left.y) { - top_left.y = pos.y; - } - if (pos.y < bottom_right.y) { - bottom_right.y = pos.y; - } - if (pos.x > bottom_right.x) { - bottom_right.x = pos.x; - } - if (pos.x < top_left.x) { - top_left.x = pos.x; - } - } - - Vector2 size = Vector2(bottom_right.x - top_left.x, top_left.y - bottom_right.y); - - Vector2 offset = last_pos + (last_size / 2.0) + (size / 2.0); // dunno I might just keep it in one axis but diagonal feels better.... - - last_pos = offset; - last_size = size; - - for (int j = 0; j < nodes.size(); j += 3) { - add_node(name, nodes[j], nodes[j + 2], offset + nodes[j + 1]); // also add an additional buffer if you want to - } - - } else { - for (int j = 0; j < nodes.size(); j += 3) { - add_node(name, nodes[j], nodes[j + 2], nodes[j + 1]); - } + add_function(func["name"], func["function_id"]); + } + { + Array nodes = d["nodes"]; + for (int i = 0; i < nodes.size(); i += 3) { + add_node(nodes[i], nodes[i + 2], nodes[i + 1]); } - Array sequence_connections = func["sequence_connections"]; + Array sequence_connections = d["sequence_connections"]; for (int j = 0; j < sequence_connections.size(); j += 3) { - sequence_connect(name, sequence_connections[j + 0], sequence_connections[j + 1], sequence_connections[j + 2]); + sequence_connect(sequence_connections[j + 0], sequence_connections[j + 1], sequence_connections[j + 2]); } - Array data_connections = func["data_connections"]; - + Array data_connections = d["data_connections"]; for (int j = 0; j < data_connections.size(); j += 4) { - data_connect(name, data_connections[j + 0], data_connections[j + 1], data_connections[j + 2], data_connections[j + 3]); + data_connect(data_connections[j + 0], data_connections[j + 1], data_connections[j + 2], data_connections[j + 3]); } } + is_tool_script = d["is_tool_script"]; + scroll = d["scroll"]; - if (d.has("is_tool_script")) { - is_tool_script = d["is_tool_script"]; - } else { - is_tool_script = false; - } - - // Takes all the rpc methods + // Takes all the rpc methods. rpc_functions.clear(); rpc_variables.clear(); - for (Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) { - if (E->get().function_id >= 0 && E->get().nodes.find(E->get().function_id)) { - Ref<VisualScriptFunction> vsf = E->get().nodes[E->get().function_id].node; + List<StringName> fns; + functions.get_key_list(&fns); + for (const List<StringName>::Element *E = fns.front(); E; E = E->next()) { + if (functions[E->get()].func_id >= 0 && nodes.has(functions[E->get()].func_id)) { + Ref<VisualScriptFunction> vsf = nodes[functions[E->get()].func_id].node; if (vsf.is_valid()) { if (vsf->get_rpc_mode() != MultiplayerAPI::RPC_MODE_DISABLED) { ScriptNetData nd; - nd.name = E->key(); + nd.name = E->get(); nd.mode = vsf->get_rpc_mode(); if (rpc_functions.find(nd) == -1) { rpc_functions.push_back(nd); @@ -1228,8 +1083,6 @@ void VisualScript::_set_data(const Dictionary &p_data) { } } - // Visual script doesn't have rset :( - // Sort so we are 100% that they are always the same. rpc_functions.sort_custom<SortNetData>(); } @@ -1237,12 +1090,15 @@ void VisualScript::_set_data(const Dictionary &p_data) { Dictionary VisualScript::_get_data() const { Dictionary d; d["base_type"] = base_type; + Array vars; - for (const Map<StringName, Variable>::Element *E = variables.front(); E; E = E->next()) { - Dictionary var = _get_variable_info(E->key()); - var["name"] = E->key(); //make sure it's the right one - var["default_value"] = E->get().default_value; - var["export"] = E->get()._export; + List<StringName> var_names; + variables.get_key_list(&var_names); + for (const List<StringName>::Element *E = var_names.front(); E; E = E->next()) { + Dictionary var = _get_variable_info(E->get()); + var["name"] = E->get(); // Make sure it's the right one. + var["default_value"] = variables[E->get()].default_value; + var["export"] = variables[E->get()]._export; vars.push_back(var); } d["variables"] = vars; @@ -1264,78 +1120,73 @@ Dictionary VisualScript::_get_data() const { d["signals"] = sigs; Array funcs; - - for (const Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) { + List<StringName> func_names; + functions.get_key_list(&func_names); + for (const List<StringName>::Element *E = func_names.front(); E; E = E->next()) { Dictionary func; - func["name"] = E->key(); - func["function_id"] = E->get().function_id; - func["scroll"] = E->get().scroll; - - Array nodes; - - for (const Map<int, Function::NodeData>::Element *F = E->get().nodes.front(); F; F = F->next()) { - nodes.push_back(F->key()); - nodes.push_back(F->get().pos); - nodes.push_back(F->get().node); - } - - func["nodes"] = nodes; - - Array sequence_connections; - - for (const Set<SequenceConnection>::Element *F = E->get().sequence_connections.front(); F; F = F->next()) { - sequence_connections.push_back(F->get().from_node); - sequence_connections.push_back(F->get().from_output); - sequence_connections.push_back(F->get().to_node); - } - - func["sequence_connections"] = sequence_connections; - - Array data_connections; + func["name"] = E->get(); + func["function_id"] = functions[E->get()].func_id; + funcs.push_back(func); + } + d["functions"] = funcs; - for (const Set<DataConnection>::Element *F = E->get().data_connections.front(); F; F = F->next()) { - data_connections.push_back(F->get().from_node); - data_connections.push_back(F->get().from_port); - data_connections.push_back(F->get().to_node); - data_connections.push_back(F->get().to_port); - } + Array nds; + List<int> node_ids; + nodes.get_key_list(&node_ids); + for (const List<int>::Element *F = node_ids.front(); F; F = F->next()) { + nds.push_back(F->get()); + nds.push_back(nodes[F->get()].pos); + nds.push_back(nodes[F->get()].node); + } + d["nodes"] = nds; - func["data_connections"] = data_connections; + Array seqconns; + for (const Set<SequenceConnection>::Element *F = sequence_connections.front(); F; F = F->next()) { + seqconns.push_back(F->get().from_node); + seqconns.push_back(F->get().from_output); + seqconns.push_back(F->get().to_node); + } + d["sequence_connections"] = seqconns; - funcs.push_back(func); + Array dataconns; + for (const Set<DataConnection>::Element *F = data_connections.front(); F; F = F->next()) { + dataconns.push_back(F->get().from_node); + dataconns.push_back(F->get().from_port); + dataconns.push_back(F->get().to_node); + dataconns.push_back(F->get().to_port); } + d["data_connections"] = dataconns; - d["functions"] = funcs; d["is_tool_script"] = is_tool_script; - d["vs_unify"] = true; + d["scroll"] = scroll; return d; } void VisualScript::_bind_methods() { - ClassDB::bind_method(D_METHOD("add_function", "name"), &VisualScript::add_function); + ClassDB::bind_method(D_METHOD("add_function", "name", "func_node_id"), &VisualScript::add_function); ClassDB::bind_method(D_METHOD("has_function", "name"), &VisualScript::has_function); ClassDB::bind_method(D_METHOD("remove_function", "name"), &VisualScript::remove_function); ClassDB::bind_method(D_METHOD("rename_function", "name", "new_name"), &VisualScript::rename_function); - ClassDB::bind_method(D_METHOD("set_function_scroll", "name", "ofs"), &VisualScript::set_function_scroll); - ClassDB::bind_method(D_METHOD("get_function_scroll", "name"), &VisualScript::get_function_scroll); + ClassDB::bind_method(D_METHOD("set_scroll", "ofs"), &VisualScript::set_scroll); + ClassDB::bind_method(D_METHOD("get_scroll"), &VisualScript::get_scroll); - ClassDB::bind_method(D_METHOD("add_node", "func", "id", "node", "position"), &VisualScript::add_node, DEFVAL(Point2())); - ClassDB::bind_method(D_METHOD("remove_node", "func", "id"), &VisualScript::remove_node); + ClassDB::bind_method(D_METHOD("add_node", "id", "node", "position"), &VisualScript::add_node, DEFVAL(Point2())); + ClassDB::bind_method(D_METHOD("remove_node", "id"), &VisualScript::remove_node); ClassDB::bind_method(D_METHOD("get_function_node_id", "name"), &VisualScript::get_function_node_id); - ClassDB::bind_method(D_METHOD("get_node", "func", "id"), &VisualScript::get_node); - ClassDB::bind_method(D_METHOD("has_node", "func", "id"), &VisualScript::has_node); - ClassDB::bind_method(D_METHOD("set_node_position", "func", "id", "position"), &VisualScript::set_node_position); - ClassDB::bind_method(D_METHOD("get_node_position", "func", "id"), &VisualScript::get_node_position); + ClassDB::bind_method(D_METHOD("get_node", "id"), &VisualScript::get_node); + ClassDB::bind_method(D_METHOD("has_node", "id"), &VisualScript::has_node); + ClassDB::bind_method(D_METHOD("set_node_position", "id", "position"), &VisualScript::set_node_position); + ClassDB::bind_method(D_METHOD("get_node_position", "id"), &VisualScript::get_node_position); - ClassDB::bind_method(D_METHOD("sequence_connect", "func", "from_node", "from_output", "to_node"), &VisualScript::sequence_connect); - ClassDB::bind_method(D_METHOD("sequence_disconnect", "func", "from_node", "from_output", "to_node"), &VisualScript::sequence_disconnect); - ClassDB::bind_method(D_METHOD("has_sequence_connection", "func", "from_node", "from_output", "to_node"), &VisualScript::has_sequence_connection); + ClassDB::bind_method(D_METHOD("sequence_connect", "from_node", "from_output", "to_node"), &VisualScript::sequence_connect); + ClassDB::bind_method(D_METHOD("sequence_disconnect", "from_node", "from_output", "to_node"), &VisualScript::sequence_disconnect); + ClassDB::bind_method(D_METHOD("has_sequence_connection", "from_node", "from_output", "to_node"), &VisualScript::has_sequence_connection); - ClassDB::bind_method(D_METHOD("data_connect", "func", "from_node", "from_port", "to_node", "to_port"), &VisualScript::data_connect); - ClassDB::bind_method(D_METHOD("data_disconnect", "func", "from_node", "from_port", "to_node", "to_port"), &VisualScript::data_disconnect); - ClassDB::bind_method(D_METHOD("has_data_connection", "func", "from_node", "from_port", "to_node", "to_port"), &VisualScript::has_data_connection); + ClassDB::bind_method(D_METHOD("data_connect", "from_node", "from_port", "to_node", "to_port"), &VisualScript::data_connect); + ClassDB::bind_method(D_METHOD("data_disconnect", "from_node", "from_port", "to_node", "to_port"), &VisualScript::data_disconnect); + ClassDB::bind_method(D_METHOD("has_data_connection", "from_node", "from_port", "to_node", "to_port"), &VisualScript::has_data_connection); ClassDB::bind_method(D_METHOD("add_variable", "name", "default_value", "export"), &VisualScript::add_variable, DEFVAL(Variant()), DEFVAL(false)); ClassDB::bind_method(D_METHOD("has_variable", "name"), &VisualScript::has_variable); @@ -1371,7 +1222,7 @@ void VisualScript::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data"); - ADD_SIGNAL(MethodInfo("node_ports_changed", PropertyInfo(Variant::STRING, "function"), PropertyInfo(Variant::INT, "id"))); + ADD_SIGNAL(MethodInfo("node_ports_changed", PropertyInfo(Variant::INT, "id"))); } VisualScript::VisualScript() { @@ -1380,16 +1231,12 @@ VisualScript::VisualScript() { } bool VisualScript::inherits_script(const Ref<Script> &p_script) const { - return this == p_script.ptr(); //there is no inheritance in visual scripts, so this is enough -} - -StringName VisualScript::get_default_func() const { - return StringName("f_312843592"); + return this == p_script.ptr(); // There is no inheritance in visual scripts, so this is enough. } -Set<int> VisualScript::get_output_sequence_ports_connected(const String &edited_func, int from_node) { +Set<int> VisualScript::get_output_sequence_ports_connected(int from_node) { List<VisualScript::SequenceConnection> *sc = memnew(List<VisualScript::SequenceConnection>); - get_sequence_connection_list(edited_func, sc); + get_sequence_connection_list(sc); Set<int> connected; for (List<VisualScript::SequenceConnection>::Element *E = sc->front(); E; E = E->next()) { if (E->get().from_node == from_node) { @@ -1401,8 +1248,11 @@ Set<int> VisualScript::get_output_sequence_ports_connected(const String &edited_ } VisualScript::~VisualScript() { - while (!functions.is_empty()) { - remove_function(functions.front()->key()); + // Remove all nodes and stuff that hold data refs. + List<int> nds; + nodes.get_key_list(&nds); + for (const List<int>::Element *E = nds.front(); E; E = E->next()) { + remove_node(E->get()); } } @@ -1430,20 +1280,21 @@ bool VisualScriptInstance::get(const StringName &p_name, Variant &r_ret) const { } void VisualScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const { - for (const Map<StringName, VisualScript::Variable>::Element *E = script->variables.front(); E; E = E->next()) { - if (!E->get()._export) { + List<StringName> vars; + script->variables.get_key_list(&vars); + for (const List<StringName>::Element *E = vars.front(); E; E = E->next()) { + if (!script->variables[E->get()]._export) { continue; } - PropertyInfo p = E->get().info; - p.name = String(E->key()); + PropertyInfo p = script->variables[E->get()].info; + p.name = String(E->get()); p.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE; p_properties->push_back(p); } } Variant::Type VisualScriptInstance::get_property_type(const StringName &p_name, bool *r_is_valid) const { - const Map<StringName, VisualScript::Variable>::Element *E = script->variables.find(p_name); - if (!E) { + if (!script->variables.has(p_name)) { if (r_is_valid) { *r_is_valid = false; } @@ -1454,19 +1305,17 @@ Variant::Type VisualScriptInstance::get_property_type(const StringName &p_name, *r_is_valid = true; } - return E->get().info.type; + return script->variables[p_name].info.type; } void VisualScriptInstance::get_method_list(List<MethodInfo> *p_list) const { - for (const Map<StringName, VisualScript::Function>::Element *E = script->functions.front(); E; E = E->next()) { - if (E->key() == script->get_default_func()) { - continue; - } - + List<StringName> fns; + script->functions.get_key_list(&fns); + for (const List<StringName>::Element *E = fns.front(); E; E = E->next()) { MethodInfo mi; - mi.name = E->key(); - if (E->get().function_id >= 0 && E->get().nodes.has(E->get().function_id)) { - Ref<VisualScriptFunction> vsf = E->get().nodes[E->get().function_id].node; + mi.name = E->get(); + if (script->functions[E->get()].func_id >= 0 && script->nodes.has(script->functions[E->get()].func_id)) { + Ref<VisualScriptFunction> vsf = script->nodes[script->functions[E->get()].func_id].node; if (vsf.is_valid()) { for (int i = 0; i < vsf->get_argument_count(); i++) { PropertyInfo arg; @@ -1476,21 +1325,16 @@ void VisualScriptInstance::get_method_list(List<MethodInfo> *p_list) const { mi.arguments.push_back(arg); } - if (!vsf->is_sequenced()) { //assumed constant if not sequenced + if (!vsf->is_sequenced()) { // Assumed constant if not sequenced. mi.flags |= METHOD_FLAG_CONST; } } } - p_list->push_back(mi); } } bool VisualScriptInstance::has_method(const StringName &p_method) const { - if (p_method == script->get_default_func()) { - return false; - } - return script->functions.has(p_method); } @@ -1522,10 +1366,10 @@ void VisualScriptInstance::_dependency_step(VisualScriptNodeInstance *node, int int index = node->input_ports[i] & VisualScriptNodeInstance::INPUT_MASK; if (node->input_ports[i] & VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT) { - //is a default value (unassigned input port) + // Is a default value (unassigned input port). input_args[i] = &default_values[index]; } else { - //regular temporary in stack + // Rregular temporary in stack. input_args[i] = &variant_stack[index]; } } @@ -1536,7 +1380,7 @@ void VisualScriptInstance::_dependency_step(VisualScriptNodeInstance *node, int Variant *working_mem = node->working_mem_idx >= 0 ? &variant_stack[node->working_mem_idx] : (Variant *)nullptr; node->step(input_args, output_args, VisualScriptNodeInstance::START_MODE_BEGIN_SEQUENCE, working_mem, r_error, error_str); - //ignore return + // Ignore return. if (r_error.error != Callable::CallError::CALL_OK) { *r_error_node = node; } @@ -1547,7 +1391,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p ERR_FAIL_COND_V(!F, Variant()); Function *f = &F->get(); - //this call goes separate, so it can e yielded and suspended + // This call goes separate, so it can e yielded and suspended. Variant *variant_stack = (Variant *)p_stack; bool *sequence_bits = (bool *)(variant_stack + f->max_stack); const Variant **input_args = (const Variant **)(sequence_bits + f->node_count); @@ -1573,25 +1417,25 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p #endif while (true) { - p_pass++; //increment pass + p_pass++; // Increment pass. current_node_id = node->get_id(); VSDEBUG("==========AT NODE: " + itos(current_node_id) + " base: " + node->get_base_node()->get_class_name()); VSDEBUG("AT STACK POS: " + itos(flow_stack_pos)); - //setup working mem + // Setup working mem. working_mem = node->working_mem_idx >= 0 ? &variant_stack[node->working_mem_idx] : (Variant *)nullptr; VSDEBUG("WORKING MEM: " + itos(node->working_mem_idx)); if (current_node_id == f->node) { - //if function node, set up function arguments from beginning of stack + // If function node, set up function arguments from beginning of stack. for (int i = 0; i < f->argument_count; i++) { input_args[i] = &variant_stack[i]; } } else { - //run dependencies first + // Run dependencies first. if (!node->dependencies.is_empty()) { int dc = node->dependencies.size(); @@ -1608,18 +1452,18 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p } if (!error) { - //setup input pointers normally + // Setup input pointers normally. VSDEBUG("INPUT PORTS: " + itos(node->input_port_count)); for (int i = 0; i < node->input_port_count; i++) { int index = node->input_ports[i] & VisualScriptNodeInstance::INPUT_MASK; if (node->input_ports[i] & VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT) { - //is a default value (unassigned input port) + // Is a default value (unassigned input port). input_args[i] = &default_values[index]; VSDEBUG("\tPORT " + itos(i) + " DEFAULT VAL"); } else { - //regular temporary in stack + // Regular temporary in stack. input_args[i] = &variant_stack[index]; VSDEBUG("PORT " + itos(i) + " AT STACK " + itos(index)); } @@ -1631,7 +1475,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p break; } - //setup output pointers + // Setup output pointers. VSDEBUG("OUTPUT PORTS: " + itos(node->output_port_count)); for (int i = 0; i < node->output_port_count; i++) { @@ -1639,15 +1483,15 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p VSDEBUG("PORT " + itos(i) + " AT STACK " + itos(node->output_ports[i])); } - //do step + // Do step. VisualScriptNodeInstance::StartMode start_mode; { if (p_resuming_yield) { start_mode = VisualScriptNodeInstance::START_MODE_RESUME_YIELD; - p_resuming_yield = false; // should resume only the first time + p_resuming_yield = false; // Should resume only the first time. } else if (flow_stack && (flow_stack[flow_stack_pos] & VisualScriptNodeInstance::FLOW_STACK_PUSHED_BIT)) { - //if there is a push bit, it means we are continuing a sequence + // If there is a push bit, it means we are continuing a sequence. start_mode = VisualScriptNodeInstance::START_MODE_CONTINUE_SEQUENCE; } else { start_mode = VisualScriptNodeInstance::START_MODE_BEGIN_SEQUENCE; @@ -1659,13 +1503,13 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p int ret = node->step(input_args, output_args, start_mode, working_mem, r_error, error_str); if (r_error.error != Callable::CallError::CALL_OK) { - //use error from step + // Use error from step. error = true; break; } if (ret & VisualScriptNodeInstance::STEP_YIELD_BIT) { - //yielded! + // Yielded! if (node->get_working_memory_size() == 0) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; error_str = RTR("A node yielded without working memory, please read the docs on how to yield properly!"); @@ -1681,7 +1525,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p break; } - //step 1, capture all state + // Step 1, capture all state. state->instance_id = get_owner_ptr()->get_instance_id(); state->script_id = get_script()->get_instance_id(); state->instance = this; @@ -1693,11 +1537,11 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p state->stack.resize(p_stack_size); state->pass = p_pass; copymem(state->stack.ptrw(), p_stack, p_stack_size); - //step 2, run away, return directly + // Step 2, run away, return directly. r_error.error = Callable::CallError::CALL_OK; #ifdef DEBUG_ENABLED - //will re-enter later, so exiting + // Will re-enter later, so exiting. if (EngineDebugger::is_active()) { VisualScriptLanguage::singleton->exit_function(); } @@ -1742,18 +1586,18 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p error_str = RTR("Return value must be assigned to first element of node working memory! Fix your node please."); error = true; } else { - //assign from working memory, first element + // Assign from working memory, first element. return_value = *working_mem; } VSDEBUG("EXITING FUNCTION - VALUE " + String(return_value)); - break; //exit function requested, bye + break; // Exit function requested, bye } - VisualScriptNodeInstance *next = nullptr; //next node + VisualScriptNodeInstance *next = nullptr; // Next node. if ((ret == output || ret & VisualScriptNodeInstance::STEP_FLAG_PUSH_STACK_BIT) && node->sequence_output_count) { - //if no exit bit was set, and has sequence outputs, guess next node + // If no exit bit was set, and has sequence outputs, guess next node. if (output >= node->sequence_output_count) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; error_str = RTR("Node returned an invalid sequence output: ") + itos(output); @@ -1766,21 +1610,21 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p } if (flow_stack) { - //update flow stack pos (may have changed) + // Update flow stack pos (may have changed). flow_stack[flow_stack_pos] = current_node_id; - //add stack push bit if requested + // Add stack push bit if requested. if (ret & VisualScriptNodeInstance::STEP_FLAG_PUSH_STACK_BIT) { flow_stack[flow_stack_pos] |= VisualScriptNodeInstance::FLOW_STACK_PUSHED_BIT; - sequence_bits[node->sequence_index] = true; //remember sequence bit + sequence_bits[node->sequence_index] = true; // Remember sequence bit. VSDEBUG("NEXT SEQ - FLAG BIT"); } else { - sequence_bits[node->sequence_index] = false; //forget sequence bit + sequence_bits[node->sequence_index] = false; // Forget sequence bit. VSDEBUG("NEXT SEQ - NORMAL"); } if (ret & VisualScriptNodeInstance::STEP_FLAG_GO_BACK_BIT) { - //go back request + // Go back request. if (flow_stack_pos > 0) { flow_stack_pos--; @@ -1788,20 +1632,20 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p VSDEBUG("NEXT IS GO BACK"); } else { VSDEBUG("NEXT IS GO BACK, BUT NO NEXT SO EXIT"); - break; //simply exit without value or error + break; // Simply exit without value or error. } } else if (next) { if (sequence_bits[next->sequence_index]) { - // what happened here is that we are entering a node that is in the middle of doing a sequence (pushed stack) from the front + // What happened here is that we are entering a node that is in the middle of doing a sequence (pushed stack) from the front // because each node has a working memory, we can't really do a sub-sequence // as a result, the sequence will be restarted and the stack will roll back to find where this node - // started the sequence + // started the sequence. bool found = false; for (int i = flow_stack_pos; i >= 0; i--) { if ((flow_stack[i] & VisualScriptNodeInstance::FLOW_STACK_MASK) == next->get_id()) { - flow_stack_pos = i; //roll back and remove bit + flow_stack_pos = i; // Roll back and remove bit. flow_stack[i] = next->get_id(); sequence_bits[next->sequence_index] = false; found = true; @@ -1819,7 +1663,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p VSDEBUG("RE-ENTERED A LOOP, RETURNED STACK POS TO - " + itos(flow_stack_pos)); } else { - // check for stack overflow + // Check for stack overflow. if (flow_stack_pos + 1 >= flow_max) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; error_str = RTR("Stack overflow with stack depth: ") + itos(output); @@ -1836,7 +1680,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p } } else { - //no next node, try to go back in stack to pushed bit + // No next node, try to go back in stack to pushed bit. bool found = false; @@ -1852,22 +1696,22 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p if (!found) { VSDEBUG("NO NEXT NODE, NO GO BACK, EXITING"); - break; //done, couldn't find a push stack bit + break; // Done, couldn't find a push stack bit. } VSDEBUG("NO NEXT NODE, GO BACK TO: " + itos(flow_stack_pos)); } } else { - node = next; //stackless mode, simply assign next node + node = next; // Stackless mode, simply assign next node. } } if (error) { - //error - // function, file, line, error, explanation + // Error + // Function, file, line, error, explanation. String err_file = script->get_path(); String err_func = p_method; - int err_line = current_node_id; //not a line but it works as one + int err_line = current_node_id; // Not a line but it works as one. if (node && (r_error.error != Callable::CallError::CALL_ERROR_INVALID_METHOD || error_str == String())) { if (error_str != String()) { @@ -1906,7 +1750,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p } #endif - //clean up variant stack + // Clean up variant stack. for (int i = 0; i < f->max_stack; i++) { variant_stack[i].~Variant(); } @@ -1954,7 +1798,7 @@ Variant VisualScriptInstance::call(const StringName &p_method, const Variant **p int *pass_stack = flow_stack ? (int *)(flow_stack + flow_max) : (int *)nullptr; for (int i = 0; i < f->node_count; i++) { - sequence_bits[i] = false; //all starts as false + sequence_bits[i] = false; // All starts as false. } zeromem(pass_stack, f->pass_stack_size * sizeof(int)); @@ -1988,12 +1832,12 @@ Variant VisualScriptInstance::call(const StringName &p_method, const Variant **p return Variant(); } - //allocate variant stack + // Allocate variant stack. for (int i = 0; i < f->max_stack; i++) { memnew_placement(&variant_stack[i], Variant); } - //allocate function arguments (must be copied for yield to work properly) + // Allocate function arguments (must be copied for yield to work properly). for (int i = 0; i < p_argcount; i++) { variant_stack[i] = *p_args[i]; } @@ -2002,12 +1846,12 @@ Variant VisualScriptInstance::call(const StringName &p_method, const Variant **p } void VisualScriptInstance::notification(int p_notification) { - //do nothing as this is called using virtual + // Do nothing as this is called using virtual. Variant what = p_notification; const Variant *whatp = &what; Callable::CallError ce; - call(VisualScriptLanguage::singleton->notification, &whatp, 1, ce); //do as call + call(VisualScriptLanguage::singleton->notification, &whatp, 1, ce); // Do as call. } String VisualScriptInstance::to_string(bool *r_valid) { @@ -2086,7 +1930,7 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o max_output_args = 0; if (Object::cast_to<Node>(p_owner)) { - //turn on these if they exist and base is a node + // Turn on these if they exist and base is a node. Node *node = Object::cast_to<Node>(p_owner); if (p_script->functions.has("_process")) { node->set_process(true); @@ -2105,190 +1949,236 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o } } - for (const Map<StringName, VisualScript::Variable>::Element *E = script->variables.front(); E; E = E->next()) { - variables[E->key()] = E->get().default_value; - } - - for (const Map<StringName, VisualScript::Function>::Element *E = script->functions.front(); E; E = E->next()) { - if (E->key() == script->get_default_func()) { - continue; - } - - Function function; - function.node = E->get().function_id; - function.max_stack = 0; - function.flow_stack_size = 0; - function.pass_stack_size = 0; - function.node_count = 0; - - Map<StringName, int> local_var_indices; - - if (function.node < 0) { - VisualScriptLanguage::singleton->debug_break_parse(get_script()->get_path(), 0, "No start node in function: " + String(E->key())); - - ERR_CONTINUE(function.node < 0); + // Setup variables. + { + List<StringName> keys; + script->variables.get_key_list(&keys); + for (const List<StringName>::Element *E = keys.front(); E; E = E->next()) { + variables[E->get()] = script->variables[E->get()].default_value; } + } - { - Ref<VisualScriptFunction> func_node = script->get_node(E->key(), E->get().function_id); - - if (func_node.is_null()) { - VisualScriptLanguage::singleton->debug_break_parse(get_script()->get_path(), 0, "No VisualScriptFunction typed start node in function: " + String(E->key())); + // Setup functions from sequence trees. + { + List<StringName> keys; + script->functions.get_key_list(&keys); + for (const List<StringName>::Element *E = keys.front(); E; E = E->next()) { + const VisualScript::Function vsfn = p_script->functions[E->get()]; + Function function; + function.node = vsfn.func_id; + function.max_stack = 0; + function.flow_stack_size = 0; + function.pass_stack_size = 0; + function.node_count = 0; + + Map<StringName, int> local_var_indices; + + if (function.node < 0) { + VisualScriptLanguage::singleton->debug_break_parse(get_script()->get_path(), 0, "No start node in function: " + String(E->get())); + ERR_CONTINUE(function.node < 0); } - ERR_CONTINUE(!func_node.is_valid()); - - function.argument_count = func_node->get_argument_count(); - function.max_stack += function.argument_count; - function.flow_stack_size = func_node->is_stack_less() ? 0 : func_node->get_stack_size(); - max_input_args = MAX(max_input_args, function.argument_count); - } - - //multiple passes are required to set up this complex thing.. - - //first create the nodes - for (const Map<int, VisualScript::Function::NodeData>::Element *F = E->get().nodes.front(); F; F = F->next()) { - Ref<VisualScriptNode> node = F->get().node; - - VisualScriptNodeInstance *instance = node->instance(this); //create instance - ERR_FAIL_COND(!instance); + { + Ref<VisualScriptFunction> func_node = script->get_node(vsfn.func_id); - instance->base = node.ptr(); + if (func_node.is_null()) { + VisualScriptLanguage::singleton->debug_break_parse(get_script()->get_path(), 0, "No VisualScriptFunction typed start node in function: " + String(E->get())); + } - instance->id = F->key(); - instance->input_port_count = node->get_input_value_port_count(); - instance->input_ports = nullptr; - instance->output_port_count = node->get_output_value_port_count(); - instance->output_ports = nullptr; - instance->sequence_output_count = node->get_output_sequence_port_count(); - instance->sequence_index = function.node_count++; - instance->sequence_outputs = nullptr; - instance->pass_idx = -1; + ERR_CONTINUE(!func_node.is_valid()); - if (instance->input_port_count) { - instance->input_ports = memnew_arr(int, instance->input_port_count); - for (int i = 0; i < instance->input_port_count; i++) { - instance->input_ports[i] = -1; //if not assigned, will become default value - } + function.argument_count = func_node->get_argument_count(); + function.max_stack += function.argument_count; + function.flow_stack_size = func_node->is_stack_less() ? 0 : func_node->get_stack_size(); + max_input_args = MAX(max_input_args, function.argument_count); } - - if (instance->output_port_count) { - instance->output_ports = memnew_arr(int, instance->output_port_count); - for (int i = 0; i < instance->output_port_count; i++) { - instance->output_ports[i] = -1; //if not assigned, will output to trash + // Function nodes graphs. + Set<VisualScript::SequenceConnection> seqconns; + Set<VisualScript::DataConnection> dataconns; + Set<int> node_ids; + node_ids.insert(function.node); + { + List<int> nd_queue; + nd_queue.push_back(function.node); + while (!nd_queue.is_empty()) { + for (const Set<VisualScript::SequenceConnection>::Element *F = script->sequence_connections.front(); F; F = F->next()) { + if (nd_queue.front()->get() == F->get().from_node && !node_ids.has(F->get().to_node)) { + nd_queue.push_back(F->get().to_node); + node_ids.insert(F->get().to_node); + } + if (nd_queue.front()->get() == F->get().from_node && !seqconns.has(F->get())) { + seqconns.insert(F->get()); + } + } + nd_queue.pop_front(); } - } - - if (instance->sequence_output_count) { - instance->sequence_outputs = memnew_arr(VisualScriptNodeInstance *, instance->sequence_output_count); - for (int i = 0; i < instance->sequence_output_count; i++) { - instance->sequence_outputs[i] = nullptr; //if it remains null, flow ends here + HashMap<int, HashMap<int, Pair<int, int>>> dc_lut; // :: to -> to_port -> (from, from_port) + for (const Set<VisualScript::DataConnection>::Element *F = script->data_connections.front(); F; F = F->next()) { + dc_lut[F->get().to_node][F->get().to_port] = Pair<int, int>(F->get().from_node, F->get().from_port); + } + for (const Set<int>::Element *F = node_ids.front(); F; F = F->next()) { + nd_queue.push_back(F->get()); + } + List<int> dc_keys; + while (!nd_queue.is_empty()) { + int ky = nd_queue.front()->get(); + dc_lut[ky].get_key_list(&dc_keys); + for (const List<int>::Element *F = dc_keys.front(); F; F = F->next()) { + VisualScript::DataConnection dc; + dc.from_node = dc_lut[ky][F->get()].first; + dc.from_port = dc_lut[ky][F->get()].second; + dc.to_node = ky; + dc.to_port = F->get(); + dataconns.insert(dc); + nd_queue.push_back(dc.from_node); + node_ids.insert(dc.from_node); + } + dc_keys.clear(); // Necessary as get_key_list does a push_back not a set. + nd_queue.pop_front(); } } - if (Object::cast_to<VisualScriptLocalVar>(node.ptr()) || Object::cast_to<VisualScriptLocalVarSet>(*node)) { - //working memory is shared only for this node, for the same variables - Ref<VisualScriptLocalVar> vslv = node; - - StringName var_name; + //Multiple passes are required to set up this complex thing.. + //First create the nodes. + for (const Set<int>::Element *F = node_ids.front(); F; F = F->next()) { + Ref<VisualScriptNode> node = script->nodes[F->get()].node; + + VisualScriptNodeInstance *instance = node->instance(this); // Create instance. + ERR_FAIL_COND(!instance); + + instance->base = node.ptr(); + + instance->id = F->get(); + instance->input_port_count = node->get_input_value_port_count(); + instance->input_ports = NULL; + instance->output_port_count = node->get_output_value_port_count(); + instance->output_ports = NULL; + instance->sequence_output_count = node->get_output_sequence_port_count(); + instance->sequence_index = function.node_count++; + instance->sequence_outputs = NULL; + instance->pass_idx = -1; + + if (instance->input_port_count) { + instance->input_ports = memnew_arr(int, instance->input_port_count); + for (int i = 0; i < instance->input_port_count; i++) { + instance->input_ports[i] = -1; // If not assigned, will become default value. + } + } - if (Object::cast_to<VisualScriptLocalVar>(*node)) { - var_name = String(Object::cast_to<VisualScriptLocalVar>(*node)->get_var_name()).strip_edges(); - } else { - var_name = String(Object::cast_to<VisualScriptLocalVarSet>(*node)->get_var_name()).strip_edges(); + if (instance->output_port_count) { + instance->output_ports = memnew_arr(int, instance->output_port_count); + for (int i = 0; i < instance->output_port_count; i++) { + instance->output_ports[i] = -1; // If not assigned, will output to trash. + } } - if (!local_var_indices.has(var_name)) { - local_var_indices[var_name] = function.max_stack; - function.max_stack++; + if (instance->sequence_output_count) { + instance->sequence_outputs = memnew_arr(VisualScriptNodeInstance *, instance->sequence_output_count); + for (int i = 0; i < instance->sequence_output_count; i++) { + instance->sequence_outputs[i] = NULL; // If it remains null, flow ends here. + } } - instance->working_mem_idx = local_var_indices[var_name]; + if (Object::cast_to<VisualScriptLocalVar>(node.ptr()) || Object::cast_to<VisualScriptLocalVarSet>(*node)) { + // Working memory is shared only for this node, for the same variables. + Ref<VisualScriptLocalVar> vslv = node; - } else if (instance->get_working_memory_size()) { - instance->working_mem_idx = function.max_stack; - function.max_stack += instance->get_working_memory_size(); - } else { - instance->working_mem_idx = -1; //no working mem - } + StringName var_name; - max_input_args = MAX(max_input_args, instance->input_port_count); - max_output_args = MAX(max_output_args, instance->output_port_count); + if (Object::cast_to<VisualScriptLocalVar>(*node)) + var_name = String(Object::cast_to<VisualScriptLocalVar>(*node)->get_var_name()).strip_edges(); + else + var_name = String(Object::cast_to<VisualScriptLocalVarSet>(*node)->get_var_name()).strip_edges(); - instances[F->key()] = instance; - } + if (!local_var_indices.has(var_name)) { + local_var_indices[var_name] = function.max_stack; + function.max_stack++; + } - function.trash_pos = function.max_stack++; //create pos for trash + instance->working_mem_idx = local_var_indices[var_name]; - //second pass, do data connections + } else if (instance->get_working_memory_size()) { + instance->working_mem_idx = function.max_stack; + function.max_stack += instance->get_working_memory_size(); + } else { + instance->working_mem_idx = -1; //no working mem + } - for (const Set<VisualScript::DataConnection>::Element *F = E->get().data_connections.front(); F; F = F->next()) { - VisualScript::DataConnection dc = F->get(); - ERR_CONTINUE(!instances.has(dc.from_node)); - VisualScriptNodeInstance *from = instances[dc.from_node]; - ERR_CONTINUE(!instances.has(dc.to_node)); - VisualScriptNodeInstance *to = instances[dc.to_node]; - ERR_CONTINUE(dc.from_port >= from->output_port_count); - ERR_CONTINUE(dc.to_port >= to->input_port_count); + max_input_args = MAX(max_input_args, instance->input_port_count); + max_output_args = MAX(max_output_args, instance->output_port_count); - if (from->output_ports[dc.from_port] == -1) { - int stack_pos = function.max_stack++; - from->output_ports[dc.from_port] = stack_pos; + instances[F->get()] = instance; } - if (from->get_sequence_output_count() == 0 && to->dependencies.find(from) == -1) { - //if the node we are reading from has no output sequence, we must call step() before reading from it. - if (from->pass_idx == -1) { - from->pass_idx = function.pass_stack_size; - function.pass_stack_size++; + function.trash_pos = function.max_stack++; // create pos for trash + + // Second pass, do data connections. + for (const Set<VisualScript::DataConnection>::Element *F = dataconns.front(); F; F = F->next()) { + VisualScript::DataConnection dc = F->get(); + ERR_CONTINUE(!instances.has(dc.from_node)); + VisualScriptNodeInstance *from = instances[dc.from_node]; + ERR_CONTINUE(!instances.has(dc.to_node)); + VisualScriptNodeInstance *to = instances[dc.to_node]; + ERR_CONTINUE(dc.from_port >= from->output_port_count); + ERR_CONTINUE(dc.to_port >= to->input_port_count); + + if (from->output_ports[dc.from_port] == -1) { + int stack_pos = function.max_stack++; + from->output_ports[dc.from_port] = stack_pos; } - to->dependencies.push_back(from); - } - to->input_ports[dc.to_port] = from->output_ports[dc.from_port]; //read from wherever the stack is - } - - //third pass, do sequence connections + if (from->get_sequence_output_count() == 0 && to->dependencies.find(from) == -1) { + // If the node we are reading from has no output sequence, we must call step() before reading from it. + if (from->pass_idx == -1) { + from->pass_idx = function.pass_stack_size; + function.pass_stack_size++; + } + to->dependencies.push_back(from); + } - for (const Set<VisualScript::SequenceConnection>::Element *F = E->get().sequence_connections.front(); F; F = F->next()) { - VisualScript::SequenceConnection sc = F->get(); - ERR_CONTINUE(!instances.has(sc.from_node)); - VisualScriptNodeInstance *from = instances[sc.from_node]; - ERR_CONTINUE(!instances.has(sc.to_node)); - VisualScriptNodeInstance *to = instances[sc.to_node]; - ERR_CONTINUE(sc.from_output >= from->sequence_output_count); + to->input_ports[dc.to_port] = from->output_ports[dc.from_port]; // Read from wherever the stack is. + } - from->sequence_outputs[sc.from_output] = to; - } + // Third pass, do sequence connections. + for (const Set<VisualScript::SequenceConnection>::Element *F = seqconns.front(); F; F = F->next()) { + VisualScript::SequenceConnection sc = F->get(); + ERR_CONTINUE(!instances.has(sc.from_node)); + VisualScriptNodeInstance *from = instances[sc.from_node]; + ERR_CONTINUE(!instances.has(sc.to_node)); + VisualScriptNodeInstance *to = instances[sc.to_node]; + ERR_CONTINUE(sc.from_output >= from->sequence_output_count); - //fourth pass: - // 1) unassigned input ports to default values - // 2) connect unassigned output ports to trash + from->sequence_outputs[sc.from_output] = to; + } - for (const Map<int, VisualScript::Function::NodeData>::Element *F = E->get().nodes.front(); F; F = F->next()) { - ERR_CONTINUE(!instances.has(F->key())); + //fourth pass: + // 1) unassigned input ports to default values + // 2) connect unassigned output ports to trash + for (const Set<int>::Element *F = node_ids.front(); F; F = F->next()) { + ERR_CONTINUE(!instances.has(F->get())); - Ref<VisualScriptNode> node = F->get().node; - VisualScriptNodeInstance *instance = instances[F->key()]; + Ref<VisualScriptNode> node = script->nodes[F->get()].node; + VisualScriptNodeInstance *instance = instances[F->get()]; - // connect to default values - for (int i = 0; i < instance->input_port_count; i++) { - if (instance->input_ports[i] == -1) { - //unassigned, connect to default val - instance->input_ports[i] = default_values.size() | VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT; - default_values.push_back(node->get_default_input_value(i)); + // Connect to default values. + for (int i = 0; i < instance->input_port_count; i++) { + if (instance->input_ports[i] == -1) { + // Unassigned, connect to default val. + instance->input_ports[i] = default_values.size() | VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT; + default_values.push_back(node->get_default_input_value(i)); + } } - } - // connect to trash - for (int i = 0; i < instance->output_port_count; i++) { - if (instance->output_ports[i] == -1) { - instance->output_ports[i] = function.trash_pos; //trash is same for all + // Connect to trash. + for (int i = 0; i < instance->output_port_count; i++) { + if (instance->output_ports[i] == -1) { + instance->output_ports[i] = function.trash_pos; //trash is same for all + } } } - } - functions[E->key()] = function; + functions[E->get()] = function; + } } } @@ -2354,7 +2244,7 @@ Variant VisualScriptFunctionState::_signal_callback(const Variant **p_args, int Variant *working_mem = ((Variant *)stack.ptr()) + working_mem_index; - *working_mem = args; //arguments go to working mem. + *working_mem = args; // Arguments go to working mem. Variant ret = instance->_call_internal(function, stack.ptrw(), stack.size(), node, flow_stack_pos, pass, true, r_error); function = StringName(); //invalidate @@ -2388,7 +2278,7 @@ Variant VisualScriptFunctionState::resume(Array p_args) { Variant *working_mem = ((Variant *)stack.ptr()) + working_mem_index; - *working_mem = p_args; //arguments go to working mem. + *working_mem = p_args; // Arguments go to working mem. Variant ret = instance->_call_internal(function, stack.ptrw(), stack.size(), node, flow_stack_pos, pass, true, r_error); function = StringName(); //invalidate @@ -2498,7 +2388,7 @@ void VisualScriptLanguage::add_global_constant(const StringName &p_variable, con /* DEBUGGER FUNCTIONS */ bool VisualScriptLanguage::debug_break_parse(const String &p_file, int p_node, const String &p_error) { - //break because of parse error + // Break because of parse error. if (EngineDebugger::is_active() && Thread::get_caller_id() == Thread::get_main_id()) { _debug_parse_err_node = p_node; @@ -2666,7 +2556,7 @@ void VisualScriptLanguage::debug_get_stack_level_members(int p_level, List<Strin } void VisualScriptLanguage::debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) { - //no globals are really reachable in gdscript + // No globals are really reachable in gdscript. } String VisualScriptLanguage::debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems, int p_max_depth) { @@ -2730,19 +2620,13 @@ 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 if (EngineDebugger::is_active()) { - //debugging enabled! + // Debugging enabled! _debug_max_call_stack = dmcs; _call_stack = memnew_arr(CallLevel, _debug_max_call_stack + 1); diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h index 3b634a3e13..72362e0ef4 100644 --- a/modules/visual_script/visual_script.h +++ b/modules/visual_script/visual_script.h @@ -46,10 +46,10 @@ class VisualScriptNode : public Resource { friend class VisualScript; - Set<VisualScript *> scripts_used; + 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; @@ -83,20 +83,16 @@ public: virtual String get_text() const; virtual String get_category() const = 0; - //used by editor, this is not really saved + // Used by editor, this is not really saved. void set_breakpoint(bool p_breakpoint); bool is_breakpoint() const; 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; @@ -106,27 +102,27 @@ public: class VisualScriptNodeInstance { friend class VisualScriptInstance; - friend class VisualScriptLanguage; //for debugger + friend class VisualScriptLanguage; // For debugger. - enum { //input argument addressing + enum { // Input argument addressing. INPUT_SHIFT = 1 << 24, INPUT_MASK = INPUT_SHIFT - 1, 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 { @@ -138,13 +134,13 @@ public: enum { STEP_SHIFT = 1 << 24, STEP_MASK = STEP_SHIFT - 1, - STEP_FLAG_PUSH_STACK_BIT = STEP_SHIFT, //push bit to stack - STEP_FLAG_GO_BACK_BIT = STEP_SHIFT << 1, //go back to previous node - STEP_NO_ADVANCE_BIT = STEP_SHIFT << 2, //do not advance past this node - STEP_EXIT_FUNCTION_BIT = STEP_SHIFT << 3, //return from function - STEP_YIELD_BIT = STEP_SHIFT << 4, //yield (will find VisualScriptFunctionState state in first working memory) + STEP_FLAG_PUSH_STACK_BIT = STEP_SHIFT, // push bit to stack + STEP_FLAG_GO_BACK_BIT = STEP_SHIFT << 1, // go back to previous node + STEP_NO_ADVANCE_BIT = STEP_SHIFT << 2, // do not advance past this node + STEP_EXIT_FUNCTION_BIT = STEP_SHIFT << 3, // return from function + STEP_YIELD_BIT = STEP_SHIFT << 4, // yield (will find VisualScriptFunctionState state in first working memory) - FLOW_STACK_PUSHED_BIT = 1 << 30, //in flow stack, means bit was pushed (must go back here if end of sequence) + FLOW_STACK_PUSHED_BIT = 1 << 30, // in flow stack, means bit was pushed (must go back here if end of sequence) FLOW_STACK_MASK = FLOW_STACK_PUSHED_BIT - 1 }; @@ -157,7 +153,7 @@ public: virtual int get_working_memory_size() const { return 0; } - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) = 0; //do a step, return which sequence port to go out + virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) = 0; // Do a step, return which sequence port to go out. Ref<VisualScriptNode> get_base_node() { return Ref<VisualScriptNode>(base); } @@ -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,37 +204,35 @@ private: StringName base_type; struct Argument { String name; - Variant::Type type; + Variant::Type type = Variant::Type::NIL; }; - struct Function { - struct NodeData { - Point2 pos; - Ref<VisualScriptNode> node; - }; - - Map<int, NodeData> nodes; - - Set<SequenceConnection> sequence_connections; + struct NodeData { + Point2 pos; + Ref<VisualScriptNode> node; + }; - Set<DataConnection> data_connections; + HashMap<int, NodeData> nodes; // Can be a sparse map. - int function_id; + Set<SequenceConnection> sequence_connections; + Set<DataConnection> data_connections; - Vector2 scroll; + Vector2 scroll; - Function() { function_id = -1; } + struct Function { + int func_id; + Function() { func_id = -1; } }; struct Variable { PropertyInfo info; Variant default_value; - bool _export; - // add getter & setter options here + bool _export = false; + // Add getter & setter options here. }; - Map<StringName, Function> functions; - Map<StringName, Variable> variables; + HashMap<StringName, Function> functions; + HashMap<StringName, Variable> variables; Map<StringName, Vector<Argument>> custom_signals; Vector<ScriptNetData> rpc_functions; Vector<ScriptNetData> rpc_variables; @@ -249,7 +243,7 @@ private: #ifdef TOOLS_ENABLED Set<PlaceHolderScriptInstance *> placeholders; - //void _update_placeholder(PlaceHolderScriptInstance *p_placeholder); + // void _update_placeholder(PlaceHolderScriptInstance *p_placeholder); virtual void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder) override; void _update_placeholders(); #endif @@ -267,37 +261,38 @@ protected: public: bool inherits_script(const Ref<Script> &p_script) const override; - // TODO: Remove it in future when breaking changes are acceptable - StringName get_default_func() const; - void add_function(const StringName &p_name); + void set_scroll(const Vector2 &p_scroll); + Vector2 get_scroll() const; + + void add_function(const StringName &p_name, int p_func_node_id); bool has_function(const StringName &p_name) const; void remove_function(const StringName &p_name); void rename_function(const StringName &p_name, const StringName &p_new_name); - void set_function_scroll(const StringName &p_name, const Vector2 &p_scroll); - Vector2 get_function_scroll(const StringName &p_name) const; void get_function_list(List<StringName> *r_functions) const; int get_function_node_id(const StringName &p_name) const; void set_tool_enabled(bool p_enabled); - void add_node(const StringName &p_func, int p_id, const Ref<VisualScriptNode> &p_node, const Point2 &p_pos = Point2()); - void remove_node(const StringName &p_func, int p_id); - bool has_node(const StringName &p_func, int p_id) const; - Ref<VisualScriptNode> get_node(const StringName &p_func, int p_id) const; - void set_node_position(const StringName &p_func, int p_id, const Point2 &p_pos); - Point2 get_node_position(const StringName &p_func, int p_id) const; - void get_node_list(const StringName &p_func, List<int> *r_nodes) const; - - void sequence_connect(const StringName &p_func, int p_from_node, int p_from_output, int p_to_node); - void sequence_disconnect(const StringName &p_func, int p_from_node, int p_from_output, int p_to_node); - bool has_sequence_connection(const StringName &p_func, int p_from_node, int p_from_output, int p_to_node) const; - void get_sequence_connection_list(const StringName &p_func, List<SequenceConnection> *r_connection) const; - - void data_connect(const StringName &p_func, int p_from_node, int p_from_port, int p_to_node, int p_to_port); - void data_disconnect(const StringName &p_func, int p_from_node, int p_from_port, int p_to_node, int p_to_port); - bool has_data_connection(const StringName &p_func, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const; - void get_data_connection_list(const StringName &p_func, List<DataConnection> *r_connection) const; - bool is_input_value_port_connected(const StringName &p_func, int p_node, int p_port) const; - bool get_input_value_port_connection_source(const StringName &p_func, int p_node, int p_port, int *r_node, int *r_port) const; + void add_node(int p_id, const Ref<VisualScriptNode> &p_node, const Point2 &p_pos = Point2()); + void remove_node(int p_id); + bool has_node(int p_id) const; + Ref<VisualScriptNode> get_node(int p_id) const; + void set_node_position(int p_id, const Point2 &p_pos); + Point2 get_node_position(int p_id) const; + void get_node_list(List<int> *r_nodes) const; + + void sequence_connect(int p_from_node, int p_from_output, int p_to_node); + void sequence_disconnect(int p_from_node, int p_from_output, int p_to_node); + bool has_sequence_connection(int p_from_node, int p_from_output, int p_to_node) const; + void get_sequence_connection_list(List<SequenceConnection> *r_connection) const; + Set<int> get_output_sequence_ports_connected(int from_node); + + void data_connect(int p_from_node, int p_from_port, int p_to_node, int p_to_port); + void data_disconnect(int p_from_node, int p_from_port, int p_to_node, int p_to_port); + bool has_data_connection(int p_from_node, int p_from_port, int p_to_node, int p_to_port) const; + void get_data_connection_list(List<DataConnection> *r_connection) const; + + bool is_input_value_port_connected(int p_node, int p_port) const; + bool get_input_value_port_connection_source(int p_node, int p_port, int *r_node, int *r_port) const; void add_variable(const StringName &p_name, const Variant &p_default_value = Variant(), bool p_export = false); bool has_variable(const StringName &p_name) const; @@ -389,35 +384,35 @@ public: }; class VisualScriptInstance : public ScriptInstance { - Object *owner; + Object *owner = nullptr; Ref<VisualScript> script; - Map<StringName, Variant> variables; //using variable path, not 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; void _dependency_step(VisualScriptNodeInstance *node, int p_pass, int *pass_stack, const Variant **input_args, Variant **output_args, Variant *variant_stack, Callable::CallError &r_error, String &error_str, VisualScriptNodeInstance **r_error_node); Variant _call_internal(const StringName &p_method, void *p_stack, int p_stack_size, VisualScriptNodeInstance *p_node, int p_flow_stack_pos, int p_pass, bool p_resuming_yield, Callable::CallError &r_error); - //Map<StringName,Function> functions; - friend class VisualScriptFunctionState; //for yield - friend class VisualScriptLanguage; //for debugger + friend class VisualScriptFunctionState; // For yield. + friend class VisualScriptLanguage; // For debugger. public: virtual bool set(const StringName &p_name, const Variant &p_value); virtual bool get(const StringName &p_name, Variant &r_ret) const; @@ -481,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); @@ -509,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; @@ -538,7 +533,7 @@ public: _FORCE_INLINE_ void enter_function(VisualScriptInstance *p_instance, const StringName *p_function, Variant *p_stack, Variant **p_work_mem, int *current_id) { if (Thread::get_main_id() != Thread::get_caller_id()) { - return; //no support for other threads than main for now + return; // No support for other threads than main for now. } if (EngineDebugger::get_script_debugger()->get_lines_left() > 0 && EngineDebugger::get_script_debugger()->get_depth() >= 0) { @@ -546,7 +541,7 @@ public: } if (_debug_call_stack_pos >= _debug_max_call_stack) { - //stack overflow + // Stack overflow. _debug_error = "Stack Overflow (Stack Size: " + itos(_debug_max_call_stack) + ")"; EngineDebugger::get_script_debugger()->debug(this); return; @@ -562,7 +557,7 @@ public: _FORCE_INLINE_ void exit_function() { if (Thread::get_main_id() != Thread::get_caller_id()) { - return; //no support for other threads than main for now + return; // No support for other threads than main for now. } if (EngineDebugger::get_script_debugger()->get_lines_left() > 0 && EngineDebugger::get_script_debugger()->get_depth() >= 0) { @@ -640,7 +635,7 @@ public: ~VisualScriptLanguage(); }; -//aid for registering +// Aid for registering. template <class T> static Ref<VisualScriptNode> create_node_generic(const String &p_name) { Ref<T> node; diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp index 2558c1d7ec..b96311ba6c 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: { } } @@ -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 e46c4638b1..92b83f3db0 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -199,7 +199,7 @@ protected: emit_signal("changed"); } void _var_value_changed() { - _change_notify("value"); //so the whole tree is not redrawn, makes editing smoother in general + _change_notify("value"); // So the whole tree is not redrawn, makes editing smoother in general. emit_signal("changed"); } @@ -227,6 +227,19 @@ protected: undo_redo->create_action(TTR("Set Variable Type")); undo_redo->add_do_method(script.ptr(), "set_variable_info", var, dc); undo_redo->add_undo_method(script.ptr(), "set_variable_info", var, d); + + // Setting the default value. + Variant::Type type = (Variant::Type)(int)p_value; + if (type != Variant::NIL) { + Variant default_value; + Callable::CallError ce; + Variant::construct(type, default_value, nullptr, 0, ce); + if (ce.error == Callable::CallError::CALL_OK) { + undo_redo->add_do_method(script.ptr(), "set_variable_default_value", var, default_value); + undo_redo->add_undo_method(script.ptr(), "set_variable_default_value", var, dc["value"]); + } + } + undo_redo->add_do_method(this, "_var_changed"); undo_redo->add_undo_method(this, "_var_changed"); undo_redo->commit_action(); @@ -309,7 +322,7 @@ protected: } p_list->push_back(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, argt)); p_list->push_back(PropertyInfo(script->get_variable_info(var).type, "value", script->get_variable_info(var).hint, script->get_variable_info(var).hint_string, PROPERTY_USAGE_DEFAULT)); - // Update this when PropertyHint changes + // Update this when PropertyHint changes. p_list->push_back(PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_ENUM, "None,Range,ExpRange,Enum,ExpEasing,Length,SpriteFrame,KeyAccel,Flags,Layers2dRender,Layers2dPhysics,Layer3dRender,Layer3dPhysics,File,Dir,GlobalFile,GlobalDir,ResourceType,MultilineText,PlaceholderText,ColorNoAlpha,ImageCompressLossy,ImageCompressLossLess,ObjectId,String,NodePathToEditedNode,MethodOfVariantType,MethodOfBaseType,MethodOfInstance,MethodOfScript,PropertyOfVariantType,PropertyOfBaseType,PropertyOfInstance,PropertyOfScript,ObjectTooBig,NodePathValidTypes")); p_list->push_back(PropertyInfo(Variant::STRING, "hint_string")); p_list->push_back(PropertyInfo(Variant::BOOL, "export")); @@ -546,39 +559,29 @@ static Color _color_from_type(Variant::Type p_type, bool dark_theme = true) { void VisualScriptEditor::_update_graph_connections() { graph->clear_connections(); - List<StringName> funcs; - script->get_function_list(&funcs); + List<VisualScript::SequenceConnection> sequence_conns; + script->get_sequence_connection_list(&sequence_conns); - if (funcs.size() <= 0) { - updating_graph = false; - return; + for (List<VisualScript::SequenceConnection>::Element *E = sequence_conns.front(); E; E = E->next()) { + graph->connect_node(itos(E->get().from_node), E->get().from_output, itos(E->get().to_node), 0); } - for (List<StringName>::Element *F = funcs.front(); F; F = F->next()) { - List<VisualScript::SequenceConnection> sequence_conns; - script->get_sequence_connection_list(F->get(), &sequence_conns); - - for (List<VisualScript::SequenceConnection>::Element *E = sequence_conns.front(); E; E = E->next()) { - graph->connect_node(itos(E->get().from_node), E->get().from_output, itos(E->get().to_node), 0); - } - - List<VisualScript::DataConnection> data_conns; - script->get_data_connection_list(F->get(), &data_conns); + List<VisualScript::DataConnection> data_conns; + script->get_data_connection_list(&data_conns); - for (List<VisualScript::DataConnection>::Element *E = data_conns.front(); E; E = E->next()) { - VisualScript::DataConnection dc = E->get(); + for (List<VisualScript::DataConnection>::Element *E = data_conns.front(); E; E = E->next()) { + VisualScript::DataConnection dc = E->get(); - Ref<VisualScriptNode> from_node = script->get_node(F->get(), E->get().from_node); - Ref<VisualScriptNode> to_node = script->get_node(F->get(), E->get().to_node); + Ref<VisualScriptNode> from_node = script->get_node(E->get().from_node); + Ref<VisualScriptNode> to_node = script->get_node(E->get().to_node); - if (to_node->has_input_sequence_port()) { - dc.to_port++; - } + if (to_node->has_input_sequence_port()) { + dc.to_port++; + } - dc.from_port += from_node->get_output_sequence_port_count(); + dc.from_port += from_node->get_output_sequence_port_count(); - graph->connect_node(itos(E->get().from_node), dc.from_port, itos(E->get().to_node), dc.to_port); - } + graph->connect_node(itos(E->get().from_node), dc.from_port, itos(E->get().to_node), dc.to_port); } } @@ -605,17 +608,6 @@ void VisualScriptEditor::_update_graph(int p_only_id) { } } } - - List<StringName> funcs; - script->get_function_list(&funcs); - - if (funcs.size() <= 0) { - graph->hide(); - select_func_text->show(); - updating_graph = false; - return; - } - graph->show(); select_func_text->hide(); @@ -655,348 +647,351 @@ void VisualScriptEditor::_update_graph(int p_only_id) { }; Ref<Texture2D> seq_port = Control::get_theme_icon("VisualShaderPort", "EditorIcons"); + List<int> node_ids; + script->get_node_list(&node_ids); - for (List<StringName>::Element *F = funcs.front(); F; F = F->next()) { // loop through all the functions - - List<int> ids; - script->get_node_list(F->get(), &ids); - StringName editor_icons = "EditorIcons"; + List<int> ids; + script->get_node_list(&ids); + StringName editor_icons = "EditorIcons"; - for (List<int>::Element *E = ids.front(); E; E = E->next()) { - if (p_only_id >= 0 && p_only_id != E->get()) { - continue; - } + for (List<int>::Element *E = ids.front(); E; E = E->next()) { + if (p_only_id >= 0 && p_only_id != E->get()) { + continue; + } - Ref<VisualScriptNode> node = script->get_node(F->get(), E->get()); - Vector2 pos = script->get_node_position(F->get(), E->get()); + Ref<VisualScriptNode> node = script->get_node(E->get()); + Vector2 pos = script->get_node_position(E->get()); - GraphNode *gnode = memnew(GraphNode); - gnode->set_title(node->get_caption()); - gnode->set_position_offset(pos * EDSCALE); - if (error_line == E->get()) { - gnode->set_overlay(GraphNode::OVERLAY_POSITION); - } else if (node->is_breakpoint()) { - gnode->set_overlay(GraphNode::OVERLAY_BREAKPOINT); - } + GraphNode *gnode = memnew(GraphNode); + gnode->set_title(node->get_caption()); + gnode->set_position_offset(pos * EDSCALE); + if (error_line == E->get()) { + gnode->set_overlay(GraphNode::OVERLAY_POSITION); + } else if (node->is_breakpoint()) { + gnode->set_overlay(GraphNode::OVERLAY_BREAKPOINT); + } - gnode->set_meta("__vnode", node); - gnode->set_name(itos(E->get())); - gnode->connect("dragged", callable_mp(this, &VisualScriptEditor::_node_moved), varray(E->get())); - gnode->connect("close_request", callable_mp(this, &VisualScriptEditor::_remove_node), varray(E->get()), CONNECT_DEFERRED); + gnode->set_meta("__vnode", node); + gnode->set_name(itos(E->get())); + gnode->connect("dragged", callable_mp(this, &VisualScriptEditor::_node_moved), varray(E->get())); + gnode->connect("close_request", callable_mp(this, &VisualScriptEditor::_remove_node), varray(E->get()), CONNECT_DEFERRED); - if (E->get() != script->get_function_node_id(F->get())) { - //function can't be erased + { + Ref<VisualScriptFunction> v = node; + if (!v.is_valid()) { gnode->set_show_close_button(true); } + } - bool has_gnode_text = false; + bool has_gnode_text = false; - Ref<VisualScriptLists> nd_list = node; - bool is_vslist = nd_list.is_valid(); - if (is_vslist) { - HBoxContainer *hbnc = memnew(HBoxContainer); + Ref<VisualScriptLists> nd_list = node; + bool is_vslist = nd_list.is_valid(); + if (is_vslist) { + HBoxContainer *hbnc = memnew(HBoxContainer); + if (nd_list->is_input_port_editable()) { + has_gnode_text = true; + Button *btn = memnew(Button); + btn->set_text(TTR("Add Input Port")); + hbnc->add_child(btn); + btn->connect("pressed", callable_mp(this, &VisualScriptEditor::_add_input_port), varray(E->get()), CONNECT_DEFERRED); + } + if (nd_list->is_output_port_editable()) { if (nd_list->is_input_port_editable()) { - has_gnode_text = true; - Button *btn = memnew(Button); - btn->set_text(TTR("Add Input Port")); - hbnc->add_child(btn); - btn->connect("pressed", callable_mp(this, &VisualScriptEditor::_add_input_port), varray(E->get()), CONNECT_DEFERRED); - } - if (nd_list->is_output_port_editable()) { - if (nd_list->is_input_port_editable()) { - hbnc->add_spacer(); - } - has_gnode_text = true; - Button *btn = memnew(Button); - btn->set_text(TTR("Add Output Port")); - hbnc->add_child(btn); - btn->connect("pressed", callable_mp(this, &VisualScriptEditor::_add_output_port), varray(E->get()), CONNECT_DEFERRED); + hbnc->add_spacer(); } - gnode->add_child(hbnc); - } else if (Object::cast_to<VisualScriptExpression>(node.ptr())) { has_gnode_text = true; - LineEdit *line_edit = memnew(LineEdit); - line_edit->set_text(node->get_text()); - line_edit->set_expand_to_text_length(true); - line_edit->add_theme_font_override("font", get_theme_font("source", "EditorFonts")); - line_edit->add_theme_font_size_override("font_size", get_theme_font_size("source_size", "EditorFonts")); - gnode->add_child(line_edit); - line_edit->connect("text_changed", callable_mp(this, &VisualScriptEditor::_expression_text_changed), varray(E->get())); - } else { - String text = node->get_text(); - if (!text.is_empty()) { - has_gnode_text = true; - Label *label = memnew(Label); - label->set_text(text); - gnode->add_child(label); - } + Button *btn = memnew(Button); + btn->set_text(TTR("Add Output Port")); + hbnc->add_child(btn); + btn->connect("pressed", callable_mp(this, &VisualScriptEditor::_add_output_port), varray(E->get()), CONNECT_DEFERRED); } - - if (Object::cast_to<VisualScriptComment>(node.ptr())) { - Ref<VisualScriptComment> vsc = node; - gnode->set_comment(true); - gnode->set_resizable(true); - gnode->set_custom_minimum_size(vsc->get_size() * EDSCALE); - gnode->connect("resize_request", callable_mp(this, &VisualScriptEditor::_comment_node_resized), varray(E->get())); + gnode->add_child(hbnc); + } else if (Object::cast_to<VisualScriptExpression>(node.ptr())) { + has_gnode_text = true; + LineEdit *line_edit = memnew(LineEdit); + line_edit->set_text(node->get_text()); + line_edit->set_expand_to_text_length(true); + line_edit->add_theme_font_override("font", get_theme_font("source", "EditorFonts")); + gnode->add_child(line_edit); + line_edit->connect("text_changed", callable_mp(this, &VisualScriptEditor::_expression_text_changed), varray(E->get())); + } else { + String text = node->get_text(); + if (!text.is_empty()) { + has_gnode_text = true; + Label *label = memnew(Label); + label->set_text(text); + gnode->add_child(label); } + } - if (node_styles.has(node->get_category())) { - Ref<StyleBoxFlat> sbf = node_styles[node->get_category()]; - if (gnode->is_comment()) { - sbf = EditorNode::get_singleton()->get_theme_base()->get_theme()->get_stylebox("comment", "GraphNode"); - } + if (Object::cast_to<VisualScriptComment>(node.ptr())) { + Ref<VisualScriptComment> vsc = node; + gnode->set_comment(true); + gnode->set_resizable(true); + gnode->set_custom_minimum_size(vsc->get_size() * EDSCALE); + gnode->connect("resize_request", callable_mp(this, &VisualScriptEditor::_comment_node_resized), varray(E->get())); + } - Color c = sbf->get_border_color(); - Color ic = c; - c.a = 1; - if (EditorSettings::get_singleton()->get("interface/theme/use_graph_node_headers")) { - Color mono_color; - if (((c.r + c.g + c.b) / 3) < 0.7) { - mono_color = Color(1.0, 1.0, 1.0); - ic = Color(0.0, 0.0, 0.0, 0.7); - } else { - mono_color = Color(0.0, 0.0, 0.0); - ic = Color(1.0, 1.0, 1.0, 0.7); - } - mono_color.a = 0.85; - c = mono_color; + if (node_styles.has(node->get_category())) { + Ref<StyleBoxFlat> sbf = node_styles[node->get_category()]; + if (gnode->is_comment()) { + sbf = EditorNode::get_singleton()->get_theme_base()->get_theme()->get_stylebox("comment", "GraphNode"); + } + + Color c = sbf->get_border_color(); + Color ic = c; + c.a = 1; + if (EditorSettings::get_singleton()->get("interface/theme/use_graph_node_headers")) { + Color mono_color; + if (((c.r + c.g + c.b) / 3) < 0.7) { + mono_color = Color(1.0, 1.0, 1.0); + ic = Color(0.0, 0.0, 0.0, 0.7); + } else { + mono_color = Color(0.0, 0.0, 0.0); + ic = Color(1.0, 1.0, 1.0, 0.7); } - gnode->add_theme_color_override("title_color", c); - c.a = 0.7; - gnode->add_theme_color_override("close_color", c); - gnode->add_theme_color_override("resizer_color", ic); - gnode->add_theme_style_override("frame", sbf); + mono_color.a = 0.85; + c = mono_color; } + gnode->add_theme_color_override("title_color", c); + c.a = 0.7; + gnode->add_theme_color_override("close_color", c); + gnode->add_theme_color_override("resizer_color", ic); + gnode->add_theme_style_override("frame", sbf); + } - const Color mono_color = get_theme_color("mono_color", "Editor"); + const Color mono_color = get_theme_color("mono_color", "Editor"); - int slot_idx = 0; + int slot_idx = 0; - bool single_seq_output = node->get_output_sequence_port_count() == 1 && node->get_output_sequence_port_text(0) == String(); - if ((node->has_input_sequence_port() || single_seq_output) || has_gnode_text) { - // IF has_gnode_text is true BUT we have no sequence ports to draw (in here), - // we still draw the disabled default ones to shift up the slots by one, - // so the slots DON'T start with the content text. + bool single_seq_output = node->get_output_sequence_port_count() == 1 && node->get_output_sequence_port_text(0) == String(); + if ((node->has_input_sequence_port() || single_seq_output) || has_gnode_text) { + // IF has_gnode_text is true BUT we have no sequence ports to draw (in here), + // we still draw the disabled default ones to shift up the slots by one, + // so the slots DON'T start with the content text. - // IF has_gnode_text is false, but we DO want to draw default sequence ports, - // we draw a dummy text to take up the position of the sequence nodes, so all the other ports are still aligned correctly. - if (!has_gnode_text) { - Label *dummy = memnew(Label); - dummy->set_text(" "); - gnode->add_child(dummy); - } - gnode->set_slot(0, node->has_input_sequence_port(), TYPE_SEQUENCE, mono_color, single_seq_output, TYPE_SEQUENCE, mono_color, seq_port, seq_port); - slot_idx++; + // IF has_gnode_text is false, but we DO want to draw default sequence ports, + // we draw a dummy text to take up the position of the sequence nodes, so all the other ports are still aligned correctly. + if (!has_gnode_text) { + Label *dummy = memnew(Label); + dummy->set_text(" "); + gnode->add_child(dummy); } + gnode->set_slot(0, node->has_input_sequence_port(), TYPE_SEQUENCE, mono_color, single_seq_output, TYPE_SEQUENCE, mono_color, seq_port, seq_port); + slot_idx++; + } - int mixed_seq_ports = 0; + int mixed_seq_ports = 0; - if (!single_seq_output) { - if (node->has_mixed_input_and_sequence_ports()) { - mixed_seq_ports = node->get_output_sequence_port_count(); - } else { - for (int i = 0; i < node->get_output_sequence_port_count(); i++) { - Label *text2 = memnew(Label); - text2->set_text(node->get_output_sequence_port_text(i)); - text2->set_align(Label::ALIGN_RIGHT); - gnode->add_child(text2); - gnode->set_slot(slot_idx, false, 0, Color(), true, TYPE_SEQUENCE, mono_color, seq_port, seq_port); - slot_idx++; - } + if (!single_seq_output) { + if (node->has_mixed_input_and_sequence_ports()) { + mixed_seq_ports = node->get_output_sequence_port_count(); + } else { + for (int i = 0; i < node->get_output_sequence_port_count(); i++) { + Label *text2 = memnew(Label); + text2->set_text(node->get_output_sequence_port_text(i)); + text2->set_align(Label::ALIGN_RIGHT); + gnode->add_child(text2); + gnode->set_slot(slot_idx, false, 0, Color(), true, TYPE_SEQUENCE, mono_color, seq_port, seq_port); + slot_idx++; } } + } - for (int i = 0; i < MAX(node->get_output_value_port_count(), MAX(mixed_seq_ports, node->get_input_value_port_count())); i++) { - bool left_ok = false; - Variant::Type left_type = Variant::NIL; - String left_name; + for (int i = 0; i < MAX(node->get_output_value_port_count(), MAX(mixed_seq_ports, node->get_input_value_port_count())); i++) { + bool left_ok = false; + Variant::Type left_type = Variant::NIL; + String left_name; - if (i < node->get_input_value_port_count()) { - PropertyInfo pi = node->get_input_value_port_info(i); - left_ok = true; - left_type = pi.type; - left_name = pi.name; - } + if (i < node->get_input_value_port_count()) { + PropertyInfo pi = node->get_input_value_port_info(i); + left_ok = true; + left_type = pi.type; + left_name = pi.name; + } - bool right_ok = false; - Variant::Type right_type = Variant::NIL; - String right_name; + bool right_ok = false; + Variant::Type right_type = Variant::NIL; + String right_name; - if (i >= mixed_seq_ports && i < node->get_output_value_port_count() + mixed_seq_ports) { - PropertyInfo pi = node->get_output_value_port_info(i - mixed_seq_ports); - right_ok = true; - right_type = pi.type; - right_name = pi.name; + if (i >= mixed_seq_ports && i < node->get_output_value_port_count() + mixed_seq_ports) { + PropertyInfo pi = node->get_output_value_port_info(i - mixed_seq_ports); + right_ok = true; + right_type = pi.type; + right_name = pi.name; + } + VBoxContainer *vbc = memnew(VBoxContainer); + HBoxContainer *hbc = memnew(HBoxContainer); + HBoxContainer *hbc2 = memnew(HBoxContainer); + vbc->add_child(hbc); + vbc->add_child(hbc2); + if (left_ok) { + Ref<Texture2D> t; + if (left_type >= 0 && left_type < Variant::VARIANT_MAX) { + t = type_icons[left_type]; + } + if (t.is_valid()) { + TextureRect *tf = memnew(TextureRect); + tf->set_texture(t); + tf->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED); + hbc->add_child(tf); } - VBoxContainer *vbc = memnew(VBoxContainer); - HBoxContainer *hbc = memnew(HBoxContainer); - HBoxContainer *hbc2 = memnew(HBoxContainer); - vbc->add_child(hbc); - vbc->add_child(hbc2); - if (left_ok) { - Ref<Texture2D> t; - if (left_type >= 0 && left_type < Variant::VARIANT_MAX) { - t = type_icons[left_type]; - } - if (t.is_valid()) { - TextureRect *tf = memnew(TextureRect); - tf->set_texture(t); - tf->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED); - hbc->add_child(tf); - } - - if (is_vslist) { - if (nd_list->is_input_port_name_editable()) { - LineEdit *name_box = memnew(LineEdit); - hbc->add_child(name_box); - name_box->set_custom_minimum_size(Size2(60 * EDSCALE, 0)); - name_box->set_text(left_name); - name_box->set_expand_to_text_length(true); - name_box->connect("resized", callable_mp(this, &VisualScriptEditor::_update_node_size), varray(E->get())); - name_box->connect("focus_exited", callable_mp(this, &VisualScriptEditor::_port_name_focus_out), varray(name_box, E->get(), i, true)); - } else { - hbc->add_child(memnew(Label(left_name))); - } - - if (nd_list->is_input_port_type_editable()) { - OptionButton *opbtn = memnew(OptionButton); - for (int j = Variant::NIL; j < Variant::VARIANT_MAX; j++) { - opbtn->add_item(Variant::get_type_name(Variant::Type(j))); - } - opbtn->select(left_type); - opbtn->set_custom_minimum_size(Size2(100 * EDSCALE, 0)); - hbc->add_child(opbtn); - opbtn->connect("item_selected", callable_mp(this, &VisualScriptEditor::_change_port_type), varray(E->get(), i, true), CONNECT_DEFERRED); - } - Button *rmbtn = memnew(Button); - rmbtn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Remove", "EditorIcons")); - hbc->add_child(rmbtn); - rmbtn->connect("pressed", callable_mp(this, &VisualScriptEditor::_remove_input_port), varray(E->get(), i), CONNECT_DEFERRED); + if (is_vslist) { + if (nd_list->is_input_port_name_editable()) { + LineEdit *name_box = memnew(LineEdit); + hbc->add_child(name_box); + name_box->set_custom_minimum_size(Size2(60 * EDSCALE, 0)); + name_box->set_text(left_name); + name_box->set_expand_to_text_length(true); + name_box->connect("resized", callable_mp(this, &VisualScriptEditor::_update_node_size), varray(E->get())); + name_box->connect("focus_exited", callable_mp(this, &VisualScriptEditor::_port_name_focus_out), varray(name_box, E->get(), i, true)); } else { hbc->add_child(memnew(Label(left_name))); } - if (left_type != Variant::NIL && !script->is_input_value_port_connected(F->get(), E->get(), i)) { - PropertyInfo pi = node->get_input_value_port_info(i); - Button *button = memnew(Button); - Variant value = node->get_default_input_value(i); - if (value.get_type() != left_type) { - //different type? for now convert - //not the same, reconvert - Callable::CallError ce; - const Variant *existingp = &value; - Variant::construct(left_type, value, &existingp, 1, ce); - } - - if (left_type == Variant::COLOR) { - button->set_custom_minimum_size(Size2(30, 0) * EDSCALE); - button->connect("draw", callable_mp(this, &VisualScriptEditor::_draw_color_over_button), varray(button, value)); - } else if (left_type == Variant::OBJECT && Ref<Resource>(value).is_valid()) { - Ref<Resource> res = value; - Array arr; - arr.push_back(button->get_instance_id()); - arr.push_back(String(value)); - EditorResourcePreview::get_singleton()->queue_edited_resource_preview(res, this, "_button_resource_previewed", arr); - - } else if (pi.type == Variant::INT && pi.hint == PROPERTY_HINT_ENUM) { - button->set_text(pi.hint_string.get_slice(",", value)); - } else { - button->set_text(value); + if (nd_list->is_input_port_type_editable()) { + OptionButton *opbtn = memnew(OptionButton); + for (int j = Variant::NIL; j < Variant::VARIANT_MAX; j++) { + opbtn->add_item(Variant::get_type_name(Variant::Type(j))); } - button->connect("pressed", callable_mp(this, &VisualScriptEditor::_default_value_edited), varray(button, E->get(), i)); - hbc2->add_child(button); + opbtn->select(left_type); + opbtn->set_custom_minimum_size(Size2(100 * EDSCALE, 0)); + hbc->add_child(opbtn); + opbtn->connect("item_selected", callable_mp(this, &VisualScriptEditor::_change_port_type), varray(E->get(), i, true), CONNECT_DEFERRED); } + + Button *rmbtn = memnew(Button); + rmbtn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Remove", "EditorIcons")); + hbc->add_child(rmbtn); + rmbtn->connect("pressed", callable_mp(this, &VisualScriptEditor::_remove_input_port), varray(E->get(), i), CONNECT_DEFERRED); } else { - Control *c = memnew(Control); - c->set_custom_minimum_size(Size2(10, 0) * EDSCALE); - hbc->add_child(c); + hbc->add_child(memnew(Label(left_name))); } - hbc->add_spacer(); - hbc2->add_spacer(); + if (left_type != Variant::NIL && !script->is_input_value_port_connected(E->get(), i)) { + PropertyInfo pi = node->get_input_value_port_info(i); + Button *button = memnew(Button); + Variant value = node->get_default_input_value(i); + if (value.get_type() != left_type) { + //different type? for now convert + //not the same, reconvert + Callable::CallError ce; + const Variant *existingp = &value; + Variant::construct(left_type, value, &existingp, 1, ce); + } - if (i < mixed_seq_ports) { - Label *text2 = memnew(Label); - text2->set_text(node->get_output_sequence_port_text(i)); - text2->set_align(Label::ALIGN_RIGHT); - hbc->add_child(text2); + if (left_type == Variant::COLOR) { + button->set_custom_minimum_size(Size2(30, 0) * EDSCALE); + button->connect("draw", callable_mp(this, &VisualScriptEditor::_draw_color_over_button), varray(button, value)); + } else if (left_type == Variant::OBJECT && Ref<Resource>(value).is_valid()) { + Ref<Resource> res = value; + Array arr; + arr.push_back(button->get_instance_id()); + arr.push_back(String(value)); + EditorResourcePreview::get_singleton()->queue_edited_resource_preview(res, this, "_button_resource_previewed", arr); + + } else if (pi.type == Variant::INT && pi.hint == PROPERTY_HINT_ENUM) { + button->set_text(pi.hint_string.get_slice(",", value)); + } else { + button->set_text(value); + } + button->connect("pressed", callable_mp(this, &VisualScriptEditor::_default_value_edited), varray(button, E->get(), i)); + hbc2->add_child(button); } + } else { + Control *c = memnew(Control); + c->set_custom_minimum_size(Size2(10, 0) * EDSCALE); + hbc->add_child(c); + } - if (right_ok) { - if (is_vslist) { - Button *rmbtn = memnew(Button); - rmbtn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Remove", "EditorIcons")); - hbc->add_child(rmbtn); - rmbtn->connect("pressed", callable_mp(this, &VisualScriptEditor::_remove_output_port), varray(E->get(), i), CONNECT_DEFERRED); - - if (nd_list->is_output_port_type_editable()) { - OptionButton *opbtn = memnew(OptionButton); - for (int j = Variant::NIL; j < Variant::VARIANT_MAX; j++) { - opbtn->add_item(Variant::get_type_name(Variant::Type(j))); - } - opbtn->select(right_type); - opbtn->set_custom_minimum_size(Size2(100 * EDSCALE, 0)); - hbc->add_child(opbtn); - opbtn->connect("item_selected", callable_mp(this, &VisualScriptEditor::_change_port_type), varray(E->get(), i, false), CONNECT_DEFERRED); - } + hbc->add_spacer(); + hbc2->add_spacer(); - if (nd_list->is_output_port_name_editable()) { - LineEdit *name_box = memnew(LineEdit); - hbc->add_child(name_box); - name_box->set_custom_minimum_size(Size2(60 * EDSCALE, 0)); - name_box->set_text(right_name); - name_box->set_expand_to_text_length(true); - name_box->connect("resized", callable_mp(this, &VisualScriptEditor::_update_node_size), varray(E->get())); - name_box->connect("focus_exited", callable_mp(this, &VisualScriptEditor::_port_name_focus_out), varray(name_box, E->get(), i, false)); - } else { - hbc->add_child(memnew(Label(right_name))); + if (i < mixed_seq_ports) { + Label *text2 = memnew(Label); + text2->set_text(node->get_output_sequence_port_text(i)); + text2->set_align(Label::ALIGN_RIGHT); + hbc->add_child(text2); + } + + if (right_ok) { + if (is_vslist) { + Button *rmbtn = memnew(Button); + rmbtn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Remove", "EditorIcons")); + hbc->add_child(rmbtn); + rmbtn->connect("pressed", callable_mp(this, &VisualScriptEditor::_remove_output_port), varray(E->get(), i), CONNECT_DEFERRED); + + if (nd_list->is_output_port_type_editable()) { + OptionButton *opbtn = memnew(OptionButton); + for (int j = Variant::NIL; j < Variant::VARIANT_MAX; j++) { + opbtn->add_item(Variant::get_type_name(Variant::Type(j))); } - } else { - hbc->add_child(memnew(Label(right_name))); + opbtn->select(right_type); + opbtn->set_custom_minimum_size(Size2(100 * EDSCALE, 0)); + hbc->add_child(opbtn); + opbtn->connect("item_selected", callable_mp(this, &VisualScriptEditor::_change_port_type), varray(E->get(), i, false), CONNECT_DEFERRED); } - Ref<Texture2D> t; - if (right_type >= 0 && right_type < Variant::VARIANT_MAX) { - t = type_icons[right_type]; - } - if (t.is_valid()) { - TextureRect *tf = memnew(TextureRect); - tf->set_texture(t); - tf->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED); - hbc->add_child(tf); + if (nd_list->is_output_port_name_editable()) { + LineEdit *name_box = memnew(LineEdit); + hbc->add_child(name_box); + name_box->set_custom_minimum_size(Size2(60 * EDSCALE, 0)); + name_box->set_text(right_name); + name_box->set_expand_to_text_length(true); + name_box->connect("resized", callable_mp(this, &VisualScriptEditor::_update_node_size), varray(E->get())); + name_box->connect("focus_exited", callable_mp(this, &VisualScriptEditor::_port_name_focus_out), varray(name_box, E->get(), i, false)); + } else { + hbc->add_child(memnew(Label(right_name))); } - } - - gnode->add_child(vbc); - - bool dark_theme = get_theme_constant("dark_theme", "Editor"); - if (i < mixed_seq_ports) { - gnode->set_slot(slot_idx, left_ok, left_type, _color_from_type(left_type, dark_theme), true, TYPE_SEQUENCE, mono_color, Ref<Texture2D>(), seq_port); } else { - gnode->set_slot(slot_idx, left_ok, left_type, _color_from_type(left_type, dark_theme), right_ok, right_type, _color_from_type(right_type, dark_theme)); + hbc->add_child(memnew(Label(right_name))); } - slot_idx++; + Ref<Texture2D> t; + if (right_type >= 0 && right_type < Variant::VARIANT_MAX) { + t = type_icons[right_type]; + } + if (t.is_valid()) { + TextureRect *tf = memnew(TextureRect); + tf->set_texture(t); + tf->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED); + hbc->add_child(tf); + } } - graph->add_child(gnode); + gnode->add_child(vbc); - if (gnode->is_comment()) { - graph->move_child(gnode, 0); + bool dark_theme = get_theme_constant("dark_theme", "Editor"); + if (i < mixed_seq_ports) { + gnode->set_slot(slot_idx, left_ok, left_type, _color_from_type(left_type, dark_theme), true, TYPE_SEQUENCE, mono_color, Ref<Texture2D>(), seq_port); + } else { + gnode->set_slot(slot_idx, left_ok, left_type, _color_from_type(left_type, dark_theme), right_ok, right_type, _color_from_type(right_type, dark_theme)); } + + slot_idx++; + } + + graph->add_child(gnode); + + if (gnode->is_comment()) { + graph->move_child(gnode, 0); } } + _update_graph_connections(); - // 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_function_scroll(default_func) * EDSCALE); + + 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; } void VisualScriptEditor::_change_port_type(int p_select, int p_id, int p_port, bool is_input) { - StringName func = _get_function_of_node(p_id); - - Ref<VisualScriptLists> vsn = script->get_node(func, p_id); + Ref<VisualScriptLists> vsn = script->get_node(p_id); if (!vsn.is_valid()) { return; } @@ -1015,14 +1010,12 @@ void VisualScriptEditor::_change_port_type(int p_select, int p_id, int p_port, b void VisualScriptEditor::_update_node_size(int p_id) { Node *node = graph->get_node(itos(p_id)); if (Object::cast_to<Control>(node)) { - Object::cast_to<Control>(node)->set_size(Vector2(1, 1)); //shrink if text is smaller + Object::cast_to<Control>(node)->set_size(Vector2(1, 1)); // Shrink if text is smaller. } } void VisualScriptEditor::_port_name_focus_out(const Node *p_name_box, int p_id, int p_port, bool is_input) { - StringName func = _get_function_of_node(p_id); - - Ref<VisualScriptLists> vsn = script->get_node(func, p_id); + Ref<VisualScriptLists> vsn = script->get_node(p_id); if (!vsn.is_valid()) { return; } @@ -1063,11 +1056,8 @@ void VisualScriptEditor::_update_members() { List<StringName> func_names; script->get_function_list(&func_names); + func_names.sort_custom<StringName::AlphCompare>(); for (List<StringName>::Element *E = func_names.front(); E; E = E->next()) { - if (E->get() == default_func) { - continue; - } - TreeItem *ti = members->create_item(functions); ti->set_text(0, E->get()); ti->set_selectable(0, true); @@ -1200,7 +1190,7 @@ void VisualScriptEditor::_member_selected() { #endif if (held_ctrl) { ERR_FAIL_COND(!script->has_function(selected)); - _center_on_node(selected, script->get_function_node_id(selected)); + _center_on_node(script->get_function_node_id(selected)); } } } @@ -1243,8 +1233,8 @@ void VisualScriptEditor::_member_edited() { int node_id = script->get_function_node_id(name); Ref<VisualScriptFunction> func; - if (script->has_node(name, node_id)) { - func = script->get_node(name, node_id); + if (script->has_node(node_id)) { + func = script->get_node(node_id); } undo_redo->create_action(TTR("Rename Function")); undo_redo->add_do_method(script.ptr(), "rename_function", name, new_name); @@ -1254,21 +1244,17 @@ void VisualScriptEditor::_member_edited() { undo_redo->add_undo_method(func.ptr(), "set_name", name); } - // also fix all function calls - List<StringName> flst; - script->get_function_list(&flst); - for (List<StringName>::Element *E = flst.front(); E; E = E->next()) { - List<int> lst; - script->get_node_list(E->get(), &lst); - for (List<int>::Element *F = lst.front(); F; F = F->next()) { - Ref<VisualScriptFunctionCall> fncall = script->get_node(E->get(), F->get()); - if (!fncall.is_valid()) { - continue; - } - if (fncall->get_function() == name) { - undo_redo->add_do_method(fncall.ptr(), "set_function", new_name); - undo_redo->add_undo_method(fncall.ptr(), "set_function", name); - } + // Also fix all function calls. + List<int> lst; + script->get_node_list(&lst); + for (List<int>::Element *F = lst.front(); F; F = F->next()) { + Ref<VisualScriptFunctionCall> fncall = script->get_node(F->get()); + if (!fncall.is_valid()) { + continue; + } + if (fncall->get_function() == name) { + undo_redo->add_do_method(fncall.ptr(), "set_function", new_name); + undo_redo->add_undo_method(fncall.ptr(), "set_function", name); } } @@ -1280,7 +1266,7 @@ void VisualScriptEditor::_member_edited() { undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed"); undo_redo->commit_action(); - return; //or crash because it will become invalid + return; // Or crash because it will become invalid. } if (ti->get_parent() == root->get_children()->get_next()) { @@ -1296,7 +1282,7 @@ void VisualScriptEditor::_member_edited() { undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed"); undo_redo->commit_action(); - return; //or crash because it will become invalid + return; // Or crash because it will become invalid. } if (ti->get_parent() == root->get_children()->get_next()->get_next()) { @@ -1310,7 +1296,7 @@ void VisualScriptEditor::_member_edited() { undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed"); undo_redo->commit_action(); - return; //or crash because it will become invalid + return; // Or crash because it will become invalid. } } @@ -1344,10 +1330,13 @@ void VisualScriptEditor::_create_function() { func_node->add_argument(arg_type, arg_name); } + int func_node_id = script->get_available_id(); + undo_redo->create_action(TTR("Add Function")); - undo_redo->add_do_method(script.ptr(), "add_function", name); - undo_redo->add_do_method(script.ptr(), "add_node", name, script->get_available_id(), func_node, ofs); + undo_redo->add_do_method(script.ptr(), "add_function", name, func_node_id); undo_redo->add_undo_method(script.ptr(), "remove_function", name); + undo_redo->add_do_method(script.ptr(), "add_node", func_node_id, func_node, ofs); + undo_redo->add_undo_method(script.ptr(), "remove_node", func_node_id); undo_redo->add_do_method(this, "_update_members"); undo_redo->add_undo_method(this, "_update_members"); undo_redo->add_do_method(this, "_update_graph"); @@ -1431,11 +1420,12 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt if (ti->get_parent() == root) { //main buttons if (ti == root->get_children()) { - //add function, this one uses menu + // Add function, this one uses menu. if (p_button == 1) { + // Ensure script base exists otherwise use custom base type. + ERR_FAIL_COND(script.is_null()); new_virtual_method_select->select_method_from_base_type(script->get_instance_base_type(), String(), true); - return; } else if (p_button == 0) { String name = _validate_name("new_function"); @@ -1445,11 +1435,13 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt Ref<VisualScriptFunction> func_node; func_node.instance(); func_node->set_name(name); + int fn_id = script->get_available_id(); undo_redo->create_action(TTR("Add Function")); - undo_redo->add_do_method(script.ptr(), "add_function", name); - undo_redo->add_do_method(script.ptr(), "add_node", name, script->get_available_id(), func_node, ofs); + undo_redo->add_do_method(script.ptr(), "add_function", name, fn_id); + undo_redo->add_do_method(script.ptr(), "add_node", fn_id, func_node, ofs); undo_redo->add_undo_method(script.ptr(), "remove_function", name); + undo_redo->add_do_method(script.ptr(), "remove_node", fn_id); undo_redo->add_do_method(this, "_update_members"); undo_redo->add_undo_method(this, "_update_members"); undo_redo->add_do_method(this, "_update_graph"); @@ -1461,11 +1453,11 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt _update_graph(); } - return; //or crash because it will become invalid + return; // Or crash because it will become invalid. } if (ti == root->get_children()->get_next()) { - //add variable + // Add variable. String name = _validate_name("new_variable"); selected = name; @@ -1477,11 +1469,11 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt undo_redo->add_do_method(this, "emit_signal", "edited_script_changed"); undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed"); undo_redo->commit_action(); - return; //or crash because it will become invalid + return; // Or crash because it will become invalid. } if (ti == root->get_children()->get_next()->get_next()) { - //add variable + // Add variable. String name = _validate_name("new_signal"); selected = name; @@ -1493,7 +1485,7 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt undo_redo->add_do_method(this, "emit_signal", "edited_script_changed"); undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed"); undo_redo->commit_action(); - return; //or crash because it will become invalid + return; // Or crash because it will become invalid. } } else if (ti->get_parent() == root->get_children()) { selected = ti->get_text(0); @@ -1505,9 +1497,7 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt } void VisualScriptEditor::_add_input_port(int p_id) { - StringName func = _get_function_of_node(p_id); - - Ref<VisualScriptLists> vsn = script->get_node(func, p_id); + Ref<VisualScriptLists> vsn = script->get_node(p_id); if (!vsn.is_valid()) { return; } @@ -1527,9 +1517,7 @@ void VisualScriptEditor::_add_input_port(int p_id) { } void VisualScriptEditor::_add_output_port(int p_id) { - StringName func = _get_function_of_node(p_id); - - Ref<VisualScriptLists> vsn = script->get_node(func, p_id); + Ref<VisualScriptLists> vsn = script->get_node(p_id); if (!vsn.is_valid()) { return; } @@ -1549,9 +1537,7 @@ void VisualScriptEditor::_add_output_port(int p_id) { } void VisualScriptEditor::_remove_input_port(int p_id, int p_port) { - StringName func = _get_function_of_node(p_id); - - Ref<VisualScriptLists> vsn = script->get_node(func, p_id); + Ref<VisualScriptLists> vsn = script->get_node(p_id); if (!vsn.is_valid()) { return; } @@ -1561,17 +1547,17 @@ void VisualScriptEditor::_remove_input_port(int p_id, int p_port) { undo_redo->create_action(TTR("Remove Input Port"), UndoRedo::MERGE_ENDS); int conn_from = -1, conn_port = -1; - script->get_input_value_port_connection_source(func, p_id, p_port, &conn_from, &conn_port); + script->get_input_value_port_connection_source(p_id, p_port, &conn_from, &conn_port); if (conn_from != -1) { - undo_redo->add_do_method(script.ptr(), "data_disconnect", func, conn_from, conn_port, p_id, p_port); + undo_redo->add_do_method(script.ptr(), "data_disconnect", conn_from, conn_port, p_id, p_port); } undo_redo->add_do_method(vsn.ptr(), "remove_input_data_port", p_port); undo_redo->add_do_method(this, "_update_graph", p_id); if (conn_from != -1) { - undo_redo->add_undo_method(script.ptr(), "data_connect", func, conn_from, conn_port, p_id, p_port); + undo_redo->add_undo_method(script.ptr(), "data_connect", conn_from, conn_port, p_id, p_port); } undo_redo->add_undo_method(vsn.ptr(), "add_input_data_port", vsn->get_input_value_port_info(p_port).type, vsn->get_input_value_port_info(p_port).name, p_port); @@ -1583,9 +1569,7 @@ void VisualScriptEditor::_remove_input_port(int p_id, int p_port) { } void VisualScriptEditor::_remove_output_port(int p_id, int p_port) { - StringName func = _get_function_of_node(p_id); - - Ref<VisualScriptLists> vsn = script->get_node(func, p_id); + Ref<VisualScriptLists> vsn = script->get_node(p_id); if (!vsn.is_valid()) { return; } @@ -1595,12 +1579,12 @@ void VisualScriptEditor::_remove_output_port(int p_id, int p_port) { undo_redo->create_action(TTR("Remove Output Port"), UndoRedo::MERGE_ENDS); List<VisualScript::DataConnection> data_connections; - script->get_data_connection_list(func, &data_connections); + script->get_data_connection_list(&data_connections); HashMap<int, Set<int>> conn_map; for (const List<VisualScript::DataConnection>::Element *E = data_connections.front(); E; E = E->next()) { if (E->get().from_node == p_id && E->get().from_port == p_port) { - // push into the connections map + // Push into the connections map. if (!conn_map.has(E->get().to_node)) { conn_map.set(E->get().to_node, Set<int>()); } @@ -1615,7 +1599,7 @@ void VisualScriptEditor::_remove_output_port(int p_id, int p_port) { conn_map.get_key_list(&keys); for (const List<int>::Element *E = keys.front(); E; E = E->next()) { for (const Set<int>::Element *F = conn_map[E->get()].front(); F; F = F->next()) { - undo_redo->add_undo_method(script.ptr(), "data_connect", func, p_id, p_port, E->get(), F->get()); + undo_redo->add_undo_method(script.ptr(), "data_connect", p_id, p_port, E->get(), F->get()); } } @@ -1628,9 +1612,7 @@ void VisualScriptEditor::_remove_output_port(int p_id, int p_port) { } void VisualScriptEditor::_expression_text_changed(const String &p_text, int p_id) { - StringName func = _get_function_of_node(p_id); - - Ref<VisualScriptExpression> vse = script->get_node(func, p_id); + Ref<VisualScriptExpression> vse = script->get_node(p_id); if (!vse.is_valid()) { return; } @@ -1646,7 +1628,7 @@ void VisualScriptEditor::_expression_text_changed(const String &p_text, int p_id Node *node = graph->get_node(itos(p_id)); if (Object::cast_to<Control>(node)) { - Object::cast_to<Control>(node)->set_size(Vector2(1, 1)); //shrink if text is smaller + Object::cast_to<Control>(node)->set_size(Vector2(1, 1)); // Shrink if text is smaller. } updating_graph = false; @@ -1666,19 +1648,14 @@ Vector2 VisualScriptEditor::_get_available_pos(bool centered, Vector2 ofs) const while (true) { bool exists = false; - List<StringName> all_fn; - script->get_function_list(&all_fn); - for (List<StringName>::Element *F = all_fn.front(); F; F = F->next()) { - StringName curr_fn = F->get(); - List<int> existing; - script->get_node_list(curr_fn, &existing); - for (List<int>::Element *E = existing.front(); E; E = E->next()) { - Point2 pos = script->get_node_position(curr_fn, E->get()); - if (pos.distance_to(ofs) < 50) { - ofs += Vector2(graph->get_snap(), graph->get_snap()); - exists = true; - break; - } + List<int> existing; + script->get_node_list(&existing); + for (List<int>::Element *E = existing.front(); E; E = E->next()) { + Point2 pos = script->get_node_position(E->get()); + if (pos.distance_to(ofs) < 50) { + ofs += Vector2(graph->get_snap(), graph->get_snap()); + exists = true; + break; } } if (exists) { @@ -1710,7 +1687,7 @@ String VisualScriptEditor::_validate_name(const String &p_name) const { } void VisualScriptEditor::_on_nodes_delete() { - // delete all the selected nodes + // Delete all the selected nodes. List<int> to_erase; @@ -1732,26 +1709,24 @@ void VisualScriptEditor::_on_nodes_delete() { for (List<int>::Element *F = to_erase.front(); F; F = F->next()) { int cr_node = F->get(); - StringName func = _get_function_of_node(cr_node); - - undo_redo->add_do_method(script.ptr(), "remove_node", func, cr_node); - undo_redo->add_undo_method(script.ptr(), "add_node", func, cr_node, script->get_node(func, cr_node), script->get_node_position(func, cr_node)); + undo_redo->add_do_method(script.ptr(), "remove_node", cr_node); + undo_redo->add_undo_method(script.ptr(), "add_node", cr_node, script->get_node(cr_node), script->get_node_position(cr_node)); List<VisualScript::SequenceConnection> sequence_conns; - script->get_sequence_connection_list(func, &sequence_conns); + script->get_sequence_connection_list(&sequence_conns); for (List<VisualScript::SequenceConnection>::Element *E = sequence_conns.front(); E; E = E->next()) { if (E->get().from_node == cr_node || E->get().to_node == cr_node) { - undo_redo->add_undo_method(script.ptr(), "sequence_connect", func, E->get().from_node, E->get().from_output, E->get().to_node); + undo_redo->add_undo_method(script.ptr(), "sequence_connect", E->get().from_node, E->get().from_output, E->get().to_node); } } List<VisualScript::DataConnection> data_conns; - script->get_data_connection_list(func, &data_conns); + script->get_data_connection_list(&data_conns); for (List<VisualScript::DataConnection>::Element *E = data_conns.front(); E; E = E->next()) { if (E->get().from_node == F->get() || E->get().to_node == F->get()) { - undo_redo->add_undo_method(script.ptr(), "data_connect", func, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); + undo_redo->add_undo_method(script.ptr(), "data_connect", E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); } } } @@ -1763,7 +1738,6 @@ void VisualScriptEditor::_on_nodes_delete() { void VisualScriptEditor::_on_nodes_duplicate() { Set<int> to_duplicate; - List<StringName> funcs; for (int i = 0; i < graph->get_child_count(); i++) { GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i)); @@ -1771,7 +1745,6 @@ void VisualScriptEditor::_on_nodes_duplicate() { if (gn->is_selected() && gn->is_close_button_visible()) { int id = gn->get_name().operator String().to_int(); to_duplicate.insert(id); - funcs.push_back(_get_function_of_node(id)); } } } @@ -1787,9 +1760,8 @@ void VisualScriptEditor::_on_nodes_duplicate() { HashMap<int, int> remap; for (Set<int>::Element *F = to_duplicate.front(); F; F = F->next()) { - // duplicate from the specific function but place it into the default func as it would lack the connections - StringName func = _get_function_of_node(F->get()); - Ref<VisualScriptNode> node = script->get_node(func, F->get()); + // Duplicate from the specific function but place it into the default func as it would lack the connections. + Ref<VisualScriptNode> node = script->get_node(F->get()); Ref<VisualScriptNode> dupe = node->duplicate(true); @@ -1797,25 +1769,23 @@ void VisualScriptEditor::_on_nodes_duplicate() { remap.set(F->get(), new_id); to_select.insert(new_id); - undo_redo->add_do_method(script.ptr(), "add_node", default_func, new_id, dupe, script->get_node_position(func, F->get()) + Vector2(20, 20)); - undo_redo->add_undo_method(script.ptr(), "remove_node", default_func, new_id); + undo_redo->add_do_method(script.ptr(), "add_node", new_id, dupe, script->get_node_position(F->get()) + Vector2(20, 20)); + undo_redo->add_undo_method(script.ptr(), "remove_node", new_id); } - for (List<StringName>::Element *F = funcs.front(); F; F = F->next()) { - List<VisualScript::SequenceConnection> seqs; - script->get_sequence_connection_list(F->get(), &seqs); - for (List<VisualScript::SequenceConnection>::Element *E = seqs.front(); E; E = E->next()) { - if (to_duplicate.has(E->get().from_node) && to_duplicate.has(E->get().to_node)) { - undo_redo->add_do_method(script.ptr(), "sequence_connect", default_func, remap[E->get().from_node], E->get().from_output, remap[E->get().to_node]); - } + List<VisualScript::SequenceConnection> seqs; + script->get_sequence_connection_list(&seqs); + for (List<VisualScript::SequenceConnection>::Element *E = seqs.front(); E; E = E->next()) { + if (to_duplicate.has(E->get().from_node) && to_duplicate.has(E->get().to_node)) { + undo_redo->add_do_method(script.ptr(), "sequence_connect", remap[E->get().from_node], E->get().from_output, remap[E->get().to_node]); } + } - List<VisualScript::DataConnection> data; - script->get_data_connection_list(F->get(), &data); - for (List<VisualScript::DataConnection>::Element *E = data.front(); E; E = E->next()) { - if (to_duplicate.has(E->get().from_node) && to_duplicate.has(E->get().to_node)) { - undo_redo->add_do_method(script.ptr(), "data_connect", default_func, remap[E->get().from_node], E->get().from_port, remap[E->get().to_node], E->get().to_port); - } + List<VisualScript::DataConnection> data; + script->get_data_connection_list(&data); + for (List<VisualScript::DataConnection>::Element *E = data.front(); E; E = E->next()) { + if (to_duplicate.has(E->get().from_node) && to_duplicate.has(E->get().to_node)) { + undo_redo->add_do_method(script.ptr(), "data_connect", remap[E->get().from_node], E->get().from_port, remap[E->get().to_node], E->get().to_port); } } @@ -1833,7 +1803,7 @@ void VisualScriptEditor::_on_nodes_duplicate() { } if (to_select.size()) { - EditorNode::get_singleton()->push_item(script->get_node(default_func, to_select.front()->get()).ptr()); + EditorNode::get_singleton()->push_item(script->get_node(to_select.front()->get()).ptr()); } } @@ -1846,7 +1816,7 @@ void VisualScriptEditor::_generic_search(String p_base_type, Vector2 pos, bool n new_connect_node_select->select_from_visual_script(p_base_type, false, false); // neither connecting nor reset text - // ensure that the dialog fits inside the graph + // Ensure that the dialog fits inside the graph. Size2 bounds = graph->get_global_position() + graph->get_size() - new_connect_node_select->get_size(); pos.x = pos.x > bounds.x ? bounds.x : pos.x; pos.y = pos.y > bounds.y ? bounds.y : pos.y; @@ -1907,7 +1877,7 @@ void VisualScriptEditor::_members_gui_input(const Ref<InputEvent> &p_event) { if (btn.is_valid() && btn->is_doubleclick()) { TreeItem *ti = members->get_selected(); if (ti && ti->get_parent() == members->get_root()->get_children()) { // to check if it's a function - _center_on_node(ti->get_metadata(0), script->get_function_node_id(ti->get_metadata(0))); + _center_on_node(script->get_function_node_id(ti->get_metadata(0))); } } } @@ -1925,8 +1895,8 @@ void VisualScriptEditor::_rename_function(const String &name, const String &new_ int node_id = script->get_function_node_id(name); Ref<VisualScriptFunction> func; - if (script->has_node(name, node_id)) { - func = script->get_node(name, node_id); + if (script->has_node(node_id)) { + func = script->get_node(node_id); } undo_redo->create_action(TTR("Rename Function")); undo_redo->add_do_method(script.ptr(), "rename_function", name, new_name); @@ -1936,21 +1906,17 @@ void VisualScriptEditor::_rename_function(const String &name, const String &new_ undo_redo->add_undo_method(func.ptr(), "set_name", name); } - // also fix all function calls - List<StringName> flst; - script->get_function_list(&flst); - for (List<StringName>::Element *E = flst.front(); E; E = E->next()) { - List<int> lst; - script->get_node_list(E->get(), &lst); - for (List<int>::Element *F = lst.front(); F; F = F->next()) { - Ref<VisualScriptFunctionCall> fncall = script->get_node(E->get(), F->get()); - if (!fncall.is_valid()) { - continue; - } - if (fncall->get_function() == name) { - undo_redo->add_do_method(fncall.ptr(), "set_function", new_name); - undo_redo->add_undo_method(fncall.ptr(), "set_function", name); - } + // Also fix all function calls. + List<int> lst; + script->get_node_list(&lst); + for (List<int>::Element *F = lst.front(); F; F = F->next()) { + Ref<VisualScriptFunctionCall> fncall = script->get_node(F->get()); + if (!fncall.is_valid()) { + continue; + } + if (fncall->get_function() == name) { + undo_redo->add_do_method(fncall.ptr(), "set_function", new_name); + undo_redo->add_undo_method(fncall.ptr(), "set_function", name); } } @@ -2103,7 +2069,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da ofs /= EDSCALE; - int new_id = _create_new_node_from_name(d["node_type"], ofs, default_func); + int new_id = _create_new_node_from_name(d["node_type"], ofs); Node *node = graph->get_node(itos(new_id)); if (node) { @@ -2142,8 +2108,8 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da int new_id = script->get_available_id(); undo_redo->create_action(TTR("Add Node")); - undo_redo->add_do_method(script.ptr(), "add_node", default_func, new_id, vnode, ofs); - undo_redo->add_undo_method(script.ptr(), "remove_node", default_func, new_id); + undo_redo->add_do_method(script.ptr(), "add_node", new_id, vnode, ofs); + undo_redo->add_undo_method(script.ptr(), "remove_node", new_id); undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); undo_redo->commit_action(); @@ -2171,11 +2137,11 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da int new_id = script->get_available_id(); undo_redo->create_action(TTR("Add Node")); - undo_redo->add_do_method(script.ptr(), "add_node", default_func, new_id, vnode, ofs); + undo_redo->add_do_method(script.ptr(), "add_node", new_id, vnode, ofs); undo_redo->add_do_method(vnode.ptr(), "set_base_type", script->get_instance_base_type()); undo_redo->add_do_method(vnode.ptr(), "set_function", d["function"]); - undo_redo->add_undo_method(script.ptr(), "remove_node", default_func, new_id); + undo_redo->add_undo_method(script.ptr(), "remove_node", new_id); undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); undo_redo->commit_action(); @@ -2203,8 +2169,8 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da int new_id = script->get_available_id(); undo_redo->create_action(TTR("Add Node")); - undo_redo->add_do_method(script.ptr(), "add_node", default_func, new_id, vnode, ofs); - undo_redo->add_undo_method(script.ptr(), "remove_node", default_func, new_id); + undo_redo->add_do_method(script.ptr(), "add_node", new_id, vnode, ofs); + undo_redo->add_undo_method(script.ptr(), "remove_node", new_id); undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); undo_redo->commit_action(); @@ -2232,8 +2198,8 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da int new_id = script->get_available_id(); undo_redo->create_action(TTR("Add Preload Node")); - undo_redo->add_do_method(script.ptr(), "add_node", default_func, new_id, prnode, ofs); - undo_redo->add_undo_method(script.ptr(), "remove_node", default_func, new_id); + undo_redo->add_do_method(script.ptr(), "add_node", new_id, prnode, ofs); + undo_redo->add_undo_method(script.ptr(), "remove_node", new_id); undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); undo_redo->commit_action(); @@ -2272,8 +2238,8 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da prnode.instance(); prnode->set_preload(res); - undo_redo->add_do_method(script.ptr(), "add_node", default_func, new_id, prnode, ofs); - undo_redo->add_undo_method(script.ptr(), "remove_node", default_func, new_id); + undo_redo->add_do_method(script.ptr(), "add_node", new_id, prnode, ofs); + undo_redo->add_undo_method(script.ptr(), "remove_node", new_id); new_ids.push_back(new_id); new_id++; ofs += Vector2(20, 20) * EDSCALE; @@ -2339,7 +2305,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da scene_node->set_node_path(sn->get_path_to(node)); n = scene_node; } else { - // ! Doesn't work properly + // ! Doesn't work properly. Ref<VisualScriptFunctionCall> call; call.instance(); call->set_call_mode(VisualScriptFunctionCall::CALL_MODE_NODE_PATH); @@ -2350,8 +2316,8 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da selecting_method_id = base_id; } - undo_redo->add_do_method(script.ptr(), "add_node", default_func, base_id, n, ofs); - undo_redo->add_undo_method(script.ptr(), "remove_node", default_func, base_id); + undo_redo->add_do_method(script.ptr(), "add_node", base_id, n, ofs); + undo_redo->add_undo_method(script.ptr(), "remove_node", base_id); base_id++; ofs += Vector2(25, 25); @@ -2420,13 +2386,13 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da vnode = pget; } - undo_redo->add_do_method(script.ptr(), "add_node", default_func, base_id, vnode, ofs); + undo_redo->add_do_method(script.ptr(), "add_node", base_id, vnode, ofs); undo_redo->add_do_method(vnode.ptr(), "set_property", d["property"]); if (!use_get) { undo_redo->add_do_method(vnode.ptr(), "set_default_input_value", 0, d["value"]); } - undo_redo->add_undo_method(script.ptr(), "remove_node", default_func, base_id); + undo_redo->add_undo_method(script.ptr(), "remove_node", base_id); undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); @@ -2465,12 +2431,12 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da } vnode = pget; } - undo_redo->add_do_method(script.ptr(), "add_node", default_func, base_id, vnode, ofs); + undo_redo->add_do_method(script.ptr(), "add_node", base_id, vnode, ofs); undo_redo->add_do_method(vnode.ptr(), "set_property", d["property"]); if (!use_get) { undo_redo->add_do_method(vnode.ptr(), "set_default_input_value", 0, d["value"]); } - undo_redo->add_undo_method(script.ptr(), "remove_node", default_func, base_id); + undo_redo->add_undo_method(script.ptr(), "remove_node", base_id); undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); @@ -2480,7 +2446,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da } void VisualScriptEditor::_selected_method(const String &p_method, const String &p_type, const bool p_connecting) { - Ref<VisualScriptFunctionCall> vsfc = script->get_node(default_func, selecting_method_id); + Ref<VisualScriptFunctionCall> vsfc = script->get_node(selecting_method_id); if (!vsfc.is_valid()) { return; } @@ -2538,14 +2504,6 @@ void VisualScriptEditor::set_edited_resource(const RES &p_res) { script->connect("node_ports_changed", callable_mp(this, &VisualScriptEditor::_node_ports_changed)); - default_func = script->get_default_func(); - - if (!script->has_function(default_func)) // this is the supposed default function - { - script->add_function(default_func); - script->set_edited(true); //so that if a function was added it's saved - } - _update_graph(); call_deferred("_update_members"); } @@ -2594,7 +2552,6 @@ bool VisualScriptEditor::is_unsaved() { Variant VisualScriptEditor::get_edit_state() { Dictionary d; - d["function"] = default_func; d["scroll"] = graph->get_scroll_ofs(); d["zoom"] = graph->get_zoom(); d["using_snap"] = graph->is_using_snap(); @@ -2604,9 +2561,6 @@ Variant VisualScriptEditor::get_edit_state() { void VisualScriptEditor::set_edit_state(const Variant &p_state) { Dictionary d = p_state; - if (d.has("function")) { - selected = default_func; - } _update_graph(); _update_members(); @@ -2625,11 +2579,11 @@ void VisualScriptEditor::set_edit_state(const Variant &p_state) { } } -void VisualScriptEditor::_center_on_node(const StringName &p_func, int p_id) { +void VisualScriptEditor::_center_on_node(int p_id) { Node *n = graph->get_node(itos(p_id)); GraphNode *gn = Object::cast_to<GraphNode>(n); - // clear selection + // Clear selection. for (int i = 0; i < graph->get_child_count(); i++) { GraphNode *gnd = Object::cast_to<GraphNode>(graph->get_child(i)); if (gnd) { @@ -2641,13 +2595,13 @@ void VisualScriptEditor::_center_on_node(const StringName &p_func, int p_id) { gn->set_selected(true); Vector2 new_scroll = gn->get_position_offset() - graph->get_size() * 0.5 + gn->get_size() * 0.5; graph->set_scroll_ofs(new_scroll); - script->set_function_scroll(p_func, new_scroll / EDSCALE); + script->set_scroll(new_scroll / EDSCALE); script->set_edited(true); } } void VisualScriptEditor::goto_line(int p_line, bool p_with_error) { - p_line += 1; //add one because script lines begin from 0. + p_line += 1; // Add one because script lines begin from 0. if (p_with_error) { error_line = p_line; @@ -2656,7 +2610,7 @@ void VisualScriptEditor::goto_line(int p_line, bool p_with_error) { List<StringName> functions; script->get_function_list(&functions); for (List<StringName>::Element *E = functions.front(); E; E = E->next()) { - if (script->has_node(E->get(), p_line)) { + if (script->has_node(p_line)) { _update_graph(); _update_members(); @@ -2703,11 +2657,11 @@ Array VisualScriptEditor::get_breakpoints() { script->get_function_list(&functions); for (List<StringName>::Element *E = functions.front(); E; E = E->next()) { List<int> nodes; - script->get_node_list(E->get(), &nodes); + script->get_node_list(&nodes); for (List<int>::Element *F = nodes.front(); F; F = F->next()) { - Ref<VisualScriptNode> vsn = script->get_node(E->get(), F->get()); + Ref<VisualScriptNode> vsn = script->get_node(F->get()); if (vsn->is_breakpoint()) { - breakpoints.push_back(F->get() - 1); //subtract 1 because breakpoints in text start from zero + breakpoints.push_back(F->get() - 1); // Subtract 1 because breakpoints in text start from zero. } } } @@ -2718,7 +2672,7 @@ void VisualScriptEditor::add_callback(const String &p_function, PackedStringArra if (script->has_function(p_function)) { _update_members(); _update_graph(); - _center_on_node(p_function, script->get_function_node_id(p_function)); + _center_on_node(script->get_function_node_id(p_function)); return; } @@ -2742,15 +2696,15 @@ void VisualScriptEditor::add_callback(const String &p_function, PackedStringArra func->add_argument(type, name); } - + int fn_id = script->get_available_id(); func->set_name(p_function); - script->add_function(p_function); - script->add_node(p_function, script->get_available_id(), func); + script->add_function(p_function, fn_id); + script->add_node(fn_id, func); _update_members(); _update_graph(); - _center_on_node(p_function, script->get_function_node_id(p_function)); + _center_on_node(script->get_function_node_id(p_function)); } bool VisualScriptEditor::show_members_overview() { @@ -2844,8 +2798,8 @@ void VisualScriptEditor::_end_node_move() { undo_redo->commit_action(); } -void VisualScriptEditor::_move_node(const StringName &p_func, int p_id, const Vector2 &p_to) { - if (!script->has_function(p_func)) { +void VisualScriptEditor::_move_node(int p_id, const Vector2 &p_to) { + if (!script->has_node(p_id)) { return; } @@ -2855,51 +2809,35 @@ void VisualScriptEditor::_move_node(const StringName &p_func, int p_id, const Ve Object::cast_to<GraphNode>(node)->set_position_offset(p_to); } - script->set_node_position(p_func, p_id, p_to / EDSCALE); -} - -StringName VisualScriptEditor::_get_function_of_node(int p_id) const { - List<StringName> funcs; - script->get_function_list(&funcs); - for (List<StringName>::Element *E = funcs.front(); E; E = E->next()) { - if (script->has_node(E->get(), p_id)) { - return E->get(); - } - } - - return ""; // this is passed to avoid crash and is tested against later + script->set_node_position(p_id, p_to / EDSCALE); } void VisualScriptEditor::_node_moved(Vector2 p_from, Vector2 p_to, int p_id) { - StringName func = _get_function_of_node(p_id); - - undo_redo->add_do_method(this, "_move_node", func, p_id, p_to); - undo_redo->add_undo_method(this, "_move_node", func, p_id, p_from); + undo_redo->add_do_method(this, "_move_node", p_id, p_to); + undo_redo->add_undo_method(this, "_move_node", p_id, p_from); } void VisualScriptEditor::_remove_node(int p_id) { undo_redo->create_action(TTR("Remove VisualScript Node")); - StringName func = _get_function_of_node(p_id); - - undo_redo->add_do_method(script.ptr(), "remove_node", func, p_id); - undo_redo->add_undo_method(script.ptr(), "add_node", func, p_id, script->get_node(func, p_id), script->get_node_position(func, p_id)); + undo_redo->add_do_method(script.ptr(), "remove_node", p_id); + undo_redo->add_undo_method(script.ptr(), "add_node", p_id, script->get_node(p_id), script->get_node_position(p_id)); List<VisualScript::SequenceConnection> sequence_conns; - script->get_sequence_connection_list(func, &sequence_conns); + script->get_sequence_connection_list(&sequence_conns); for (List<VisualScript::SequenceConnection>::Element *E = sequence_conns.front(); E; E = E->next()) { if (E->get().from_node == p_id || E->get().to_node == p_id) { - undo_redo->add_undo_method(script.ptr(), "sequence_connect", func, E->get().from_node, E->get().from_output, E->get().to_node); + undo_redo->add_undo_method(script.ptr(), "sequence_connect", E->get().from_node, E->get().from_output, E->get().to_node); } } List<VisualScript::DataConnection> data_conns; - script->get_data_connection_list(func, &data_conns); + script->get_data_connection_list(&data_conns); for (List<VisualScript::DataConnection>::Element *E = data_conns.front(); E; E = E->next()) { if (E->get().from_node == p_id || E->get().to_node == p_id) { - undo_redo->add_undo_method(script.ptr(), "data_connect", func, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); + undo_redo->add_undo_method(script.ptr(), "data_connect", E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); } } @@ -2909,13 +2847,13 @@ void VisualScriptEditor::_remove_node(int p_id) { undo_redo->commit_action(); } -void VisualScriptEditor::_node_ports_changed(const String &p_func, int p_id) { +void VisualScriptEditor::_node_ports_changed(int p_id) { _update_graph(p_id); } -bool VisualScriptEditor::node_has_sequence_connections(const StringName &p_func, int p_id) { +bool VisualScriptEditor::node_has_sequence_connections(int p_id) { List<VisualScript::SequenceConnection> sequence_conns; - script->get_sequence_connection_list(p_func, &sequence_conns); + script->get_sequence_connection_list(&sequence_conns); for (List<VisualScript::SequenceConnection>::Element *E = sequence_conns.front(); E; E = E->next()) { int from = E->get().from_node; @@ -2930,9 +2868,7 @@ bool VisualScriptEditor::node_has_sequence_connections(const StringName &p_func, } void VisualScriptEditor::_graph_connected(const String &p_from, int p_from_slot, const String &p_to, int p_to_slot) { - StringName from_func = _get_function_of_node(p_from.to_int()); - - Ref<VisualScriptNode> from_node = script->get_node(from_func, p_from.to_int()); + Ref<VisualScriptNode> from_node = script->get_node(p_from.to_int()); ERR_FAIL_COND(!from_node.is_valid()); bool from_seq; @@ -2942,9 +2878,7 @@ void VisualScriptEditor::_graph_connected(const String &p_from, int p_from_slot, return; //can't connect this, it's invalid } - StringName to_func = _get_function_of_node(p_to.to_int()); - - Ref<VisualScriptNode> to_node = script->get_node(to_func, p_to.to_int()); + Ref<VisualScriptNode> to_node = script->get_node(p_to.to_int()); ERR_FAIL_COND(!to_node.is_valid()); bool to_seq; @@ -2956,56 +2890,23 @@ void VisualScriptEditor::_graph_connected(const String &p_from, int p_from_slot, ERR_FAIL_COND(from_seq != to_seq); - // Do all the checks here - StringName func; // this the func where we store the one the nodes at the end of the resolution on having multiple nodes + // Do all the checks here. + StringName func; // This the func where we store the one the nodes at the end of the resolution on having multiple nodes. undo_redo->create_action(TTR("Connect Nodes")); - if (from_func == to_func) { - func = to_func; - } else if (from_seq) { - // this is a sequence connection - _move_nodes_with_rescan(to_func, from_func, p_to.to_int()); // this function moves the nodes from func1 to func2 - func = from_func; - } else { - if (node_has_sequence_connections(to_func, p_to.to_int())) { - if (node_has_sequence_connections(from_func, p_from.to_int())) { - ERR_PRINT("Trying to connect between different sequence node trees"); - return; - } else { - _move_nodes_with_rescan(from_func, to_func, p_from.to_int()); - func = to_func; - } - } else if (node_has_sequence_connections(from_func, p_from.to_int())) { - if (from_func == default_func) { - _move_nodes_with_rescan(from_func, to_func, p_from.to_int()); - func = to_func; - } else { - _move_nodes_with_rescan(to_func, from_func, p_to.to_int()); - func = from_func; - } - } else { - if (to_func == default_func) { - _move_nodes_with_rescan(to_func, from_func, p_to.to_int()); - func = from_func; - } else { - _move_nodes_with_rescan(from_func, to_func, p_from.to_int()); - func = to_func; - } - } - } - if (from_seq) { - undo_redo->add_do_method(script.ptr(), "sequence_connect", func, p_from.to_int(), from_port, p_to.to_int()); - // this undo error on undo after move can't be removed without painful gymnastics - undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", func, p_from.to_int(), from_port, p_to.to_int()); + undo_redo->add_do_method(script.ptr(), "sequence_connect", p_from.to_int(), from_port, p_to.to_int()); + // This undo error on undo after move can't be removed without painful gymnastics + undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", p_from.to_int(), from_port, p_to.to_int()); + undo_redo->add_do_method(this, "_update_graph"); + undo_redo->add_undo_method(this, "_update_graph"); } else { bool converted = false; - int conv_node = -1; Ref<VisualScriptOperator> oper = to_node; if (oper.is_valid() && oper->get_typed() == Variant::NIL) { - // it's an operator Node and if the type is already nil + // It's an operator Node and if the type is already nil if (from_node->get_output_value_port_info(from_port).type != Variant::NIL) { oper->set_typed(from_node->get_output_value_port_info(from_port).type); } @@ -3013,106 +2914,36 @@ void VisualScriptEditor::_graph_connected(const String &p_from, int p_from_slot, Ref<VisualScriptOperator> operf = from_node; if (operf.is_valid() && operf->get_typed() == Variant::NIL) { - // it's an operator Node and if the type is already nil + // It's an operator Node and if the type is already nil if (to_node->get_input_value_port_info(to_port).type != Variant::NIL) { operf->set_typed(to_node->get_input_value_port_info(to_port).type); } } - Variant::Type to_type = to_node->get_input_value_port_info(to_port).type; - Variant::Type from_type = from_node->get_output_value_port_info(from_port).type; - - if (to_type != Variant::NIL && from_type != Variant::NIL && to_type != from_type) { - // add a constructor node between the ports - bool exceptions = false; // true if there are any exceptions - exceptions = exceptions || (to_type == Variant::INT && from_type == Variant::FLOAT); - exceptions = exceptions || (to_type == Variant::FLOAT && from_type == Variant::INT); - if (Variant::can_convert(from_type, to_type) && !exceptions) { - MethodInfo mi; - mi.name = Variant::get_type_name(to_type); - PropertyInfo pi; - pi.name = "from"; - pi.type = from_type; - mi.arguments.push_back(pi); - mi.return_val.type = to_type; - // we know that this is allowed so create a new constructor node - Ref<VisualScriptConstructor> constructor; - constructor.instance(); - constructor->set_constructor_type(to_type); - constructor->set_constructor(mi); - // add the new constructor node - - GraphNode *gn = Object::cast_to<GraphNode>(graph->get_node(p_from)); - GraphNode *gn2 = Object::cast_to<GraphNode>(graph->get_node(p_to)); - if (gn && gn2) { - Vector2 from_node_size = gn->get_rect().get_size(); - Vector2 to_node_size = gn2->get_rect().get_size(); - Vector2 to_node_pos = script->get_node_position(func, p_to.to_int()); - Vector2 from_node_pos = script->get_node_position(func, p_from.to_int()); - Vector2 new_to_node_pos = from_node_pos; - Vector2 constructor_pos; - if ((to_node_pos.x - from_node_pos.x) < 0) { - // to is behind from node - if (to_node_pos.x > (from_node_pos.x - to_node_size.x - 240)) { - new_to_node_pos.x = from_node_pos.x - to_node_size.x - 240; // approx size of constructor node + padding - } else { - new_to_node_pos.x = to_node_pos.x; - } - new_to_node_pos.y = to_node_pos.y; - constructor_pos.x = from_node_pos.x - 210; - constructor_pos.y = to_node_pos.y; - } else { - // to is ahead of from node - if (to_node_pos.x < (from_node_size.x + from_node_pos.x + 240)) { - new_to_node_pos.x = from_node_size.x + from_node_pos.x + 240; // approx size of constructor node + padding - } else { - new_to_node_pos.x = to_node_pos.x; - } - new_to_node_pos.y = to_node_pos.y; - constructor_pos.x = from_node_size.x + from_node_pos.x + 10; - constructor_pos.y = to_node_pos.y; - } - undo_redo->add_do_method(this, "_move_node", func, p_to.to_int(), new_to_node_pos); - undo_redo->add_undo_method(this, "_move_node", func, p_to.to_int(), to_node_pos); - conv_node = script->get_available_id(); - undo_redo->add_do_method(script.ptr(), "add_node", func, conv_node, constructor, _get_available_pos(false, constructor_pos)); - undo_redo->add_undo_method(script.ptr(), "remove_node", func, conv_node); - converted = true; - } - } - } - - // disconnect current, and connect the new one - if (script->is_input_value_port_connected(func, p_to.to_int(), to_port)) { + // Disconnect current, and connect the new one + if (script->is_input_value_port_connected(p_to.to_int(), to_port)) { if (can_swap && data_disconnect_node == p_to.to_int()) { int conn_from; int conn_port; - script->get_input_value_port_connection_source(func, p_to.to_int(), to_port, &conn_from, &conn_port); - undo_redo->add_do_method(script.ptr(), "data_disconnect", func, conn_from, conn_port, p_to.to_int(), to_port); - undo_redo->add_do_method(script.ptr(), "data_connect", func, conn_from, conn_port, data_disconnect_node, data_disconnect_port); - undo_redo->add_undo_method(script.ptr(), "data_disconnect", func, conn_from, conn_port, data_disconnect_node, data_disconnect_port); - undo_redo->add_undo_method(script.ptr(), "data_connect", func, conn_from, conn_port, p_to.to_int(), to_port); + script->get_input_value_port_connection_source(p_to.to_int(), to_port, &conn_from, &conn_port); + undo_redo->add_do_method(script.ptr(), "data_disconnect", conn_from, conn_port, p_to.to_int(), to_port); + undo_redo->add_do_method(script.ptr(), "data_connect", conn_from, conn_port, data_disconnect_node, data_disconnect_port); + undo_redo->add_undo_method(script.ptr(), "data_disconnect", conn_from, conn_port, data_disconnect_node, data_disconnect_port); + undo_redo->add_undo_method(script.ptr(), "data_connect", conn_from, conn_port, p_to.to_int(), to_port); can_swap = false; // swapped } else { int conn_from; int conn_port; - script->get_input_value_port_connection_source(func, p_to.to_int(), to_port, &conn_from, &conn_port); - undo_redo->add_do_method(script.ptr(), "data_disconnect", func, conn_from, conn_port, p_to.to_int(), to_port); - undo_redo->add_undo_method(script.ptr(), "data_connect", func, conn_from, conn_port, p_to.to_int(), to_port); + script->get_input_value_port_connection_source(p_to.to_int(), to_port, &conn_from, &conn_port); + undo_redo->add_do_method(script.ptr(), "data_disconnect", conn_from, conn_port, p_to.to_int(), to_port); + undo_redo->add_undo_method(script.ptr(), "data_connect", conn_from, conn_port, p_to.to_int(), to_port); } } if (!converted) { - undo_redo->add_do_method(script.ptr(), "data_connect", func, p_from.to_int(), from_port, p_to.to_int(), to_port); - undo_redo->add_undo_method(script.ptr(), "data_disconnect", func, p_from.to_int(), from_port, p_to.to_int(), to_port); - } else { - // this is noice - undo_redo->add_do_method(script.ptr(), "data_connect", func, p_from.to_int(), from_port, conv_node, 0); - undo_redo->add_do_method(script.ptr(), "data_connect", func, conv_node, 0, p_to.to_int(), to_port); - // I don't think this is needed but gonna leave it here for now... until I need to finalise it all - undo_redo->add_undo_method(script.ptr(), "data_disconnect", func, p_from.to_int(), from_port, conv_node, 0); - undo_redo->add_undo_method(script.ptr(), "data_disconnect", func, conv_node, 0, p_to.to_int(), to_port); + undo_redo->add_do_method(script.ptr(), "data_connect", p_from.to_int(), from_port, p_to.to_int(), to_port); + undo_redo->add_undo_method(script.ptr(), "data_disconnect", p_from.to_int(), from_port, p_to.to_int(), to_port); } - //update nodes in graph + // Update nodes in graph if (!converted) { undo_redo->add_do_method(this, "_update_graph", p_from.to_int()); undo_redo->add_do_method(this, "_update_graph", p_to.to_int()); @@ -3124,34 +2955,28 @@ void VisualScriptEditor::_graph_connected(const String &p_from, int p_from_slot, } } - undo_redo->add_do_method(this, "_update_graph_connections"); - undo_redo->add_undo_method(this, "_update_graph_connections"); - undo_redo->commit_action(); } void VisualScriptEditor::_graph_disconnected(const String &p_from, int p_from_slot, const String &p_to, int p_to_slot) { - StringName func = _get_function_of_node(p_from.to_int()); - ERR_FAIL_COND(func != _get_function_of_node(p_to.to_int())); - - Ref<VisualScriptNode> from_node = script->get_node(func, p_from.to_int()); + Ref<VisualScriptNode> from_node = script->get_node(p_from.to_int()); ERR_FAIL_COND(!from_node.is_valid()); bool from_seq; int from_port; if (!_get_out_slot(from_node, p_from_slot, from_port, from_seq)) { - return; //can't connect this, it's invalid + return; // Can't connect this, it's invalid. } - Ref<VisualScriptNode> to_node = script->get_node(func, p_to.to_int()); + Ref<VisualScriptNode> to_node = script->get_node(p_to.to_int()); ERR_FAIL_COND(!to_node.is_valid()); bool to_seq; int to_port; if (!_get_in_slot(to_node, p_to_slot, to_port, to_seq)) { - return; //can't connect this, it's invalid + return; // Can't connect this, it's invalid. } ERR_FAIL_COND(from_seq != to_seq); @@ -3159,248 +2984,27 @@ void VisualScriptEditor::_graph_disconnected(const String &p_from, int p_from_sl undo_redo->create_action(TTR("Disconnect Nodes")); if (from_seq) { - undo_redo->add_do_method(script.ptr(), "sequence_disconnect", func, p_from.to_int(), from_port, p_to.to_int()); - undo_redo->add_undo_method(script.ptr(), "sequence_connect", func, p_from.to_int(), from_port, p_to.to_int()); + undo_redo->add_do_method(script.ptr(), "sequence_disconnect", p_from.to_int(), from_port, p_to.to_int()); + undo_redo->add_undo_method(script.ptr(), "sequence_connect", p_from.to_int(), from_port, p_to.to_int()); + undo_redo->add_do_method(this, "_update_graph"); + undo_redo->add_undo_method(this, "_update_graph"); } else { can_swap = true; data_disconnect_node = p_to.to_int(); data_disconnect_port = to_port; - undo_redo->add_do_method(script.ptr(), "data_disconnect", func, p_from.to_int(), from_port, p_to.to_int(), to_port); - undo_redo->add_undo_method(script.ptr(), "data_connect", func, p_from.to_int(), from_port, p_to.to_int(), to_port); - //update relevant nodes in the graph + undo_redo->add_do_method(script.ptr(), "data_disconnect", p_from.to_int(), from_port, p_to.to_int(), to_port); + undo_redo->add_undo_method(script.ptr(), "data_connect", p_from.to_int(), from_port, p_to.to_int(), to_port); + // Update relevant nodes in the graph. undo_redo->add_do_method(this, "_update_graph", p_from.to_int()); undo_redo->add_do_method(this, "_update_graph", p_to.to_int()); undo_redo->add_undo_method(this, "_update_graph", p_from.to_int()); undo_redo->add_undo_method(this, "_update_graph", p_to.to_int()); } - undo_redo->add_do_method(this, "_update_graph_connections"); - undo_redo->add_undo_method(this, "_update_graph_connections"); undo_redo->commit_action(); } -void VisualScriptEditor::_move_nodes_with_rescan(const StringName &p_func_from, const StringName &p_func_to, int p_id) { - Set<int> nodes_to_move; - HashMap<int, Map<int, int>> seqconns_to_move; // from => List(outp, to) - HashMap<int, Map<int, Pair<int, int>>> dataconns_to_move; // to => List(inp_p => from, outp) - - nodes_to_move.insert(p_id); - Set<int> sequence_connections; - { - List<VisualScript::SequenceConnection> sequence_conns; - script->get_sequence_connection_list(p_func_from, &sequence_conns); - - HashMap<int, Map<int, int>> seqcons; // from => List(out_p => to) - - for (List<VisualScript::SequenceConnection>::Element *E = sequence_conns.front(); E; E = E->next()) { - int from = E->get().from_node; - int to = E->get().to_node; - int out_p = E->get().from_output; - if (!seqcons.has(from)) { - seqcons.set(from, Map<int, int>()); - } - seqcons[from].insert(out_p, to); - sequence_connections.insert(to); - sequence_connections.insert(from); - } - - int conn = p_id; - List<int> stack; - HashMap<int, Set<int>> seen; // from, outp - while (seqcons.has(conn)) { - for (auto E = seqcons[conn].front(); E; E = E->next()) { - if (seen.has(conn) && seen[conn].has(E->key())) { - if (!E->next()) { - if (stack.size() > 0) { - conn = stack.back()->get(); - stack.pop_back(); - break; - } - conn = -101; - break; - } - continue; - } - if (!seen.has(conn)) { - seen.set(conn, Set<int>()); - } - seen[conn].insert(E->key()); - stack.push_back(conn); - if (!seqconns_to_move.has(conn)) { - seqconns_to_move.set(conn, Map<int, int>()); - } - seqconns_to_move[conn].insert(E->key(), E->get()); - conn = E->get(); - nodes_to_move.insert(conn); - break; - } - if (!seqcons.has(conn) && stack.size() > 0) { - conn = stack.back()->get(); - stack.pop_back(); - } - } - } - - { - List<VisualScript::DataConnection> data_connections; - script->get_data_connection_list(p_func_from, &data_connections); - int func_from_node_id = script->get_function_node_id(p_func_from); - - HashMap<int, Map<int, Pair<int, int>>> connections; - - for (List<VisualScript::DataConnection>::Element *E = data_connections.front(); E; E = E->next()) { - int from = E->get().from_node; - int to = E->get().to_node; - int out_p = E->get().from_port; - int in_p = E->get().to_port; - - // skip if the from_node is a function node - if (from == func_from_node_id) { - continue; - } - - if (!connections.has(to)) { - connections.set(to, Map<int, Pair<int, int>>()); - } - connections[to].insert(in_p, Pair<int, int>(from, out_p)); - } - - // go through the HashMap and do all sorts of crazy ass stuff now... - Set<int> nodes_to_be_added; - for (Set<int>::Element *F = nodes_to_move.front(); F; F = F->next()) { - HashMap<int, Set<int>> seen; - List<int> stack; - int id = F->get(); - while (connections.has(id)) { - for (auto E = connections[id].front(); E; E = E->next()) { - if (seen.has(id) && seen[id].has(E->key())) { - if (!E->next()) { - if (stack.size() > 0) { - id = stack.back()->get(); - stack.pop_back(); - break; - } - id = -11; // I assume ids can't be negative should confirm it... - break; - } - continue; - } - - if (sequence_connections.has(E->get().first)) { - if (!nodes_to_move.has(E->get().first)) { - if (stack.size() > 0) { - id = stack.back()->get(); - stack.pop_back(); - break; - } - id = -11; // I assume ids can't be negative should confirm it... - break; - } - } - - if (!seen.has(id)) { - seen.set(id, Set<int>()); - } - seen[id].insert(E->key()); - stack.push_back(id); - if (!dataconns_to_move.has(id)) { - dataconns_to_move.set(id, Map<int, Pair<int, int>>()); - } - dataconns_to_move[id].insert(E->key(), Pair<int, int>(E->get().first, E->get().second)); - id = E->get().first; - nodes_to_be_added.insert(id); - break; - } - if (!connections.has(id) && stack.size() > 0) { - id = stack.back()->get(); - stack.pop_back(); - } - } - } - for (Set<int>::Element *E = nodes_to_be_added.front(); E; E = E->next()) { - nodes_to_move.insert(E->get()); - } - } - - // * this is primarily for the sake of the having proper undo - List<VisualScript::SequenceConnection> seqext; - List<VisualScript::DataConnection> dataext; - - List<VisualScript::SequenceConnection> seq_connections; - script->get_sequence_connection_list(p_func_from, &seq_connections); - - for (List<VisualScript::SequenceConnection>::Element *E = seq_connections.front(); E; E = E->next()) { - if (!nodes_to_move.has(E->get().from_node) && nodes_to_move.has(E->get().to_node)) { - seqext.push_back(E->get()); - } else if (nodes_to_move.has(E->get().from_node) && !nodes_to_move.has(E->get().to_node)) { - seqext.push_back(E->get()); - } - } - - List<VisualScript::DataConnection> data_connections; - script->get_data_connection_list(p_func_from, &data_connections); - - for (List<VisualScript::DataConnection>::Element *E = data_connections.front(); E; E = E->next()) { - if (!nodes_to_move.has(E->get().from_node) && nodes_to_move.has(E->get().to_node)) { - dataext.push_back(E->get()); - } else if (nodes_to_move.has(E->get().from_node) && !nodes_to_move.has(E->get().to_node)) { - dataext.push_back(E->get()); - } - } - - // undo_redo->create_action("Rescan Functions"); - - for (Set<int>::Element *E = nodes_to_move.front(); E; E = E->next()) { - int id = E->get(); - - undo_redo->add_do_method(script.ptr(), "remove_node", p_func_from, id); - undo_redo->add_do_method(script.ptr(), "add_node", p_func_to, id, script->get_node(p_func_from, id), script->get_node_position(p_func_from, id)); - - undo_redo->add_undo_method(script.ptr(), "remove_node", p_func_to, id); - undo_redo->add_undo_method(script.ptr(), "add_node", p_func_from, id, script->get_node(p_func_from, id), script->get_node_position(p_func_from, id)); - } - - List<int> skeys; - seqconns_to_move.get_key_list(&skeys); - for (List<int>::Element *E = skeys.front(); E; E = E->next()) { - int from_node = E->get(); - for (Map<int, int>::Element *F = seqconns_to_move[from_node].front(); F; F = F->next()) { - int from_port = F->key(); - int to_node = F->get(); - undo_redo->add_do_method(script.ptr(), "sequence_connect", p_func_to, from_node, from_port, to_node); - undo_redo->add_undo_method(script.ptr(), "sequence_connect", p_func_from, from_node, from_port, to_node); - } - } - - List<int> keys; - dataconns_to_move.get_key_list(&keys); - for (List<int>::Element *E = keys.front(); E; E = E->next()) { - int to_node = E->get(); // to_node - for (Map<int, Pair<int, int>>::Element *F = dataconns_to_move[E->get()].front(); F; F = F->next()) { - int inp_p = F->key(); - Pair<int, int> fro = F->get(); - - undo_redo->add_do_method(script.ptr(), "data_connect", p_func_to, fro.first, fro.second, to_node, inp_p); - undo_redo->add_undo_method(script.ptr(), "data_connect", p_func_from, fro.first, fro.second, to_node, inp_p); - } - } - - // this to have proper undo operations - for (List<VisualScript::SequenceConnection>::Element *E = seqext.front(); E; E = E->next()) { - undo_redo->add_undo_method(script.ptr(), "sequence_connect", p_func_from, E->get().from_node, E->get().from_output, E->get().to_node); - } - for (List<VisualScript::DataConnection>::Element *E = dataext.front(); E; E = E->next()) { - undo_redo->add_undo_method(script.ptr(), "data_connect", p_func_from, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); - } - // this doesn't need do methods as they are handled by the subsequent do calls implicitly - - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - - // undo_redo->commit_action(); -} - void VisualScriptEditor::_graph_connect_to_empty(const String &p_from, int p_from_slot, const Vector2 &p_release_pos) { Node *node = graph->get_node(p_from); GraphNode *gn = Object::cast_to<GraphNode>(node); @@ -3408,23 +3012,22 @@ void VisualScriptEditor::_graph_connect_to_empty(const String &p_from, int p_fro return; } - StringName func = _get_function_of_node(p_from.to_int()); - - Ref<VisualScriptNode> vsn = script->get_node(func, p_from.to_int()); + Ref<VisualScriptNode> vsn = script->get_node(p_from.to_int()); if (!vsn.is_valid()) { return; } + if (vsn->get_output_value_port_count()) - port_action_pos = p_release_pos; + port_action_pos = p_release_pos; if (p_from_slot < vsn->get_output_sequence_port_count()) { port_action_node = p_from.to_int(); port_action_output = p_from_slot; - _port_action_menu(CREATE_ACTION, func); + _port_action_menu(CREATE_ACTION); } else { port_action_output = p_from_slot - vsn->get_output_sequence_port_count(); port_action_node = p_from.to_int(); - _port_action_menu(CREATE_CALL_SET_GET, func); + _port_action_menu(CREATE_CALL_SET_GET); } } @@ -3438,9 +3041,7 @@ VisualScriptNode::TypeGuess VisualScriptEditor::_guess_output_type(int p_port_ac visited_nodes.insert(p_port_action_node); - StringName func = _get_function_of_node(p_port_action_node); - - Ref<VisualScriptNode> node = script->get_node(func, p_port_action_node); + Ref<VisualScriptNode> node = script->get_node(p_port_action_node); if (!node.is_valid()) { return tg; @@ -3454,11 +3055,11 @@ VisualScriptNode::TypeGuess VisualScriptEditor::_guess_output_type(int p_port_ac g.type = pi.type; if (g.type == Variant::NIL || g.type == Variant::OBJECT) { - //any or object input, must further guess what this is + // Any or object input, must further guess what this is. int from_node; int from_port; - if (script->get_input_value_port_connection_source(func, p_port_action_node, i, &from_node, &from_port)) { + if (script->get_input_value_port_connection_source(p_port_action_node, i, &from_node, &from_port)) { g = _guess_output_type(from_node, from_port, visited_nodes); } else { Variant defval = node->get_default_input_value(i); @@ -3480,7 +3081,7 @@ VisualScriptNode::TypeGuess VisualScriptEditor::_guess_output_type(int p_port_ac return node->guess_output_type(in_guesses.ptrw(), p_port_action_output); } -void VisualScriptEditor::_port_action_menu(int p_option, const StringName &func) { +void VisualScriptEditor::_port_action_menu(int p_option) { Vector2 ofs = graph->get_scroll_ofs() + port_action_pos; if (graph->is_using_snap()) { int snap = graph->get_snap(); @@ -3503,8 +3104,8 @@ void VisualScriptEditor::_port_action_menu(int p_option, const StringName &func) n->set_base_type("Object"); } String type_string; - if (script->get_node(func, port_action_node)->get_output_value_port_count() > 0) { - type_string = script->get_node(func, port_action_node)->get_output_value_port_info(port_action_output).hint_string; + if (script->get_node(port_action_node)->get_output_value_port_count() > 0) { + type_string = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint_string; } if (tg.type == Variant::OBJECT) { if (tg.script.is_valid()) { @@ -3519,7 +3120,7 @@ void VisualScriptEditor::_port_action_menu(int p_option, const StringName &func) } else { new_connect_node_select->select_from_basic_type(tg.type); } - // ensure that the dialog fits inside the graph + // Ensure that the dialog fits inside the graph. Vector2 pos = mouse_up_position; Size2 bounds = graph->get_global_position() + graph->get_size() - new_connect_node_select->get_size(); pos.x = pos.x > bounds.x ? bounds.x : pos.x; @@ -3529,8 +3130,8 @@ void VisualScriptEditor::_port_action_menu(int p_option, const StringName &func) case CREATE_ACTION: { VisualScriptNode::TypeGuess tg = _guess_output_type(port_action_node, port_action_output, vn); PropertyInfo property_info; - if (script->get_node(func, port_action_node)->get_output_value_port_count() > 0) { - property_info = script->get_node(func, port_action_node)->get_output_value_port_info(port_action_output); + if (script->get_node(port_action_node)->get_output_value_port_count() > 0) { + property_info = script->get_node(port_action_node)->get_output_value_port_info(port_action_output); } if (tg.type == Variant::OBJECT) { if (property_info.type == Variant::OBJECT && property_info.hint_string != String()) { @@ -3543,7 +3144,7 @@ void VisualScriptEditor::_port_action_menu(int p_option, const StringName &func) } else { new_connect_node_select->select_from_action(Variant::get_type_name(tg.type)); } - // ensure that the dialog fits inside the graph + // Ensure that the dialog fits inside the graph. Vector2 pos = mouse_up_position; Size2 bounds = graph->get_global_position() + graph->get_size() - new_connect_node_select->get_size(); pos.x = pos.x > bounds.x ? bounds.x : pos.x; @@ -3572,9 +3173,8 @@ void VisualScriptEditor::connect_data(Ref<VisualScriptNode> vnode_old, Ref<Visua if (port >= value_count) { port = 0; } - StringName func = _get_function_of_node(port_action_node); - undo_redo->add_do_method(script.ptr(), "data_connect", func, port_action_node, port, new_id, 0); - undo_redo->add_undo_method(script.ptr(), "data_disconnect", func, port_action_node, port, new_id, 0); + undo_redo->add_do_method(script.ptr(), "data_connect", port_action_node, port, new_id, 0); + undo_redo->add_undo_method(script.ptr(), "data_disconnect", port_action_node, port, new_id, 0); undo_redo->commit_action(); } @@ -3591,17 +3191,16 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri bool port_node_exists = true; - StringName func = _get_function_of_node(port_action_node); - if (func == StringName()) { - func = default_func; - port_node_exists = false; - } + // if (func == StringName()) { + // func = default_func; + // port_node_exists = false; + // } if (p_category == "visualscript") { Ref<VisualScriptNode> vnode_new = VisualScriptLanguage::singleton->create_node_from_name(p_text); Ref<VisualScriptNode> vnode_old; - if (port_node_exists) { - vnode_old = script->get_node(func, port_action_node); + if (port_node_exists && p_connecting) { + vnode_old = script->get_node(port_action_node); } int new_id = script->get_available_id(); @@ -3624,13 +3223,13 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri } undo_redo->create_action(TTR("Add Node")); - undo_redo->add_do_method(script.ptr(), "add_node", func, new_id, vnode_new, ofs); + undo_redo->add_do_method(script.ptr(), "add_node", new_id, vnode_new, ofs); if (vnode_old.is_valid() && p_connecting) { connect_seq(vnode_old, vnode_new, new_id); connect_data(vnode_old, vnode_new, new_id); } - undo_redo->add_undo_method(script.ptr(), "remove_node", func, new_id); + undo_redo->add_undo_method(script.ptr(), "remove_node", new_id); undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); undo_redo->commit_action(); @@ -3687,8 +3286,8 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri int new_id = script->get_available_id(); undo_redo->create_action(TTR("Add Node")); - undo_redo->add_do_method(script.ptr(), "add_node", func, new_id, vnode, ofs); - undo_redo->add_undo_method(script.ptr(), "remove_node", func, new_id); + undo_redo->add_do_method(script.ptr(), "add_node", new_id, vnode, ofs); + undo_redo->add_undo_method(script.ptr(), "remove_node", new_id); undo_redo->add_do_method(this, "_update_graph", new_id); undo_redo->add_undo_method(this, "_update_graph", new_id); undo_redo->commit_action(); @@ -3699,7 +3298,7 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri port_action_new_node = new_id; - Ref<VisualScriptNode> vsn = script->get_node(func, port_action_new_node); + Ref<VisualScriptNode> vsn = script->get_node(port_action_new_node); if (Object::cast_to<VisualScriptFunctionCall>(vsn.ptr())) { Ref<VisualScriptFunctionCall> vsfc = vsn; @@ -3713,10 +3312,9 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri vsfc->set_base_type(String("")); if (tg.gdclass != StringName()) { vsfc->set_base_type(tg.gdclass); - - } else if (script->get_node(func, port_action_node).is_valid()) { - PropertyHint hint = script->get_node(func, port_action_node)->get_output_value_port_info(port_action_output).hint; - String base_type = script->get_node(func, port_action_node)->get_output_value_port_info(port_action_output).hint_string; + } else if (script->get_node(port_action_node).is_valid()) { + PropertyHint hint = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint; + String base_type = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint_string; if (base_type != String() && hint == PROPERTY_HINT_TYPE_STRING) { vsfc->set_base_type(base_type); @@ -3749,9 +3347,9 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri if (tg.gdclass != StringName()) { vsp->set_base_type(tg.gdclass); - } else if (script->get_node(func, port_action_node).is_valid()) { - PropertyHint hint = script->get_node(func, port_action_node)->get_output_value_port_info(port_action_output).hint; - String base_type = script->get_node(func, port_action_node)->get_output_value_port_info(port_action_output).hint_string; + } else if (script->get_node(port_action_node).is_valid()) { + PropertyHint hint = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint; + String base_type = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint_string; if (base_type != String() && hint == PROPERTY_HINT_TYPE_STRING) { vsp->set_base_type(base_type); @@ -3779,9 +3377,9 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri if (tg.gdclass != StringName()) { vsp->set_base_type(tg.gdclass); - } else if (script->get_node(func, port_action_node).is_valid()) { - PropertyHint hint = script->get_node(func, port_action_node)->get_output_value_port_info(port_action_output).hint; - String base_type = script->get_node(func, port_action_node)->get_output_value_port_info(port_action_output).hint_string; + } else if (script->get_node(port_action_node).is_valid()) { + PropertyHint hint = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint; + String base_type = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint_string; if (base_type != String() && hint == PROPERTY_HINT_TYPE_STRING) { vsp->set_base_type(base_type); } @@ -3799,16 +3397,13 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri } } if (port_node_exists) { - Ref<VisualScriptNode> vnode_old = script->get_node(func, port_action_node); + Ref<VisualScriptNode> vnode_old = script->get_node(port_action_node); if (vnode_old.is_valid() && p_connecting) { connect_seq(vnode_old, vnode, port_action_new_node); connect_data(vnode_old, vnode, port_action_new_node); } } _update_graph(port_action_new_node); - if (port_node_exists) { - _update_graph_connections(); - } } void VisualScriptEditor::connect_seq(Ref<VisualScriptNode> vnode_old, Ref<VisualScriptNode> vnode_new, int new_id) { @@ -3827,29 +3422,27 @@ void VisualScriptEditor::connect_seq(Ref<VisualScriptNode> vnode_old, Ref<Visual return; } - StringName func = _get_function_of_node(port_action_node); - undo_redo->create_action(TTR("Connect Node Sequence")); int pass_port = -vnode_old->get_output_sequence_port_count() + 1; int return_port = port_action_output - 1; if (vnode_old->get_output_value_port_info(port_action_output).name == String("pass") && - !script->get_output_sequence_ports_connected(func, port_action_node).has(pass_port)) { - undo_redo->add_do_method(script.ptr(), "sequence_connect", func, port_action_node, pass_port, new_id); - undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", func, port_action_node, pass_port, new_id); + !script->get_output_sequence_ports_connected(port_action_node).has(pass_port)) { + undo_redo->add_do_method(script.ptr(), "sequence_connect", port_action_node, pass_port, new_id); + undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", port_action_node, pass_port, new_id); } else if (vnode_old->get_output_value_port_info(port_action_output).name == String("return") && - !script->get_output_sequence_ports_connected(func, port_action_node).has(return_port)) { - undo_redo->add_do_method(script.ptr(), "sequence_connect", func, port_action_node, return_port, new_id); - undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", func, port_action_node, return_port, new_id); + !script->get_output_sequence_ports_connected(port_action_node).has(return_port)) { + undo_redo->add_do_method(script.ptr(), "sequence_connect", port_action_node, return_port, new_id); + undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", port_action_node, return_port, new_id); } else { for (int port = 0; port < vnode_old->get_output_sequence_port_count(); port++) { int count = vnode_old->get_output_sequence_port_count(); - if (port_action_output < count && !script->get_output_sequence_ports_connected(func, port_action_node).has(port_action_output)) { - undo_redo->add_do_method(script.ptr(), "sequence_connect", func, port_action_node, port_action_output, new_id); - undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", func, port_action_node, port_action_output, new_id); + if (port_action_output < count && !script->get_output_sequence_ports_connected(port_action_node).has(port_action_output)) { + undo_redo->add_do_method(script.ptr(), "sequence_connect", port_action_node, port_action_output, new_id); + undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", port_action_node, port_action_output, new_id); break; - } else if (!script->get_output_sequence_ports_connected(func, port_action_node).has(port)) { - undo_redo->add_do_method(script.ptr(), "sequence_connect", func, port_action_node, port, new_id); - undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", func, port_action_node, port, new_id); + } else if (!script->get_output_sequence_ports_connected(port_action_node).has(port)) { + undo_redo->add_do_method(script.ptr(), "sequence_connect", port_action_node, port, new_id); + undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", port_action_node, port, new_id); break; } } @@ -3884,9 +3477,9 @@ void VisualScriptEditor::_selected_new_virtual_method(const String &p_text, cons Ref<VisualScriptFunction> func_node; func_node.instance(); func_node->set_name(name); - + int fn_id = script->get_available_id(); undo_redo->create_action(TTR("Add Function")); - undo_redo->add_do_method(script.ptr(), "add_function", name); + undo_redo->add_do_method(script.ptr(), "add_function", name, fn_id); for (int i = 0; i < minfo.arguments.size(); i++) { func_node->add_argument(minfo.arguments[i].type, minfo.arguments[i].name, -1, minfo.arguments[i].hint, minfo.arguments[i].hint_string); @@ -3894,14 +3487,17 @@ void VisualScriptEditor::_selected_new_virtual_method(const String &p_text, cons Vector2 ofs = _get_available_pos(); - undo_redo->add_do_method(script.ptr(), "add_node", name, script->get_available_id(), func_node, ofs); + undo_redo->add_do_method(script.ptr(), "add_node", fn_id, func_node, ofs); + undo_redo->add_undo_method(script.ptr(), "remove_node", fn_id); if (minfo.return_val.type != Variant::NIL || minfo.return_val.usage & PROPERTY_USAGE_NIL_IS_VARIANT) { Ref<VisualScriptReturn> ret_node; ret_node.instance(); ret_node->set_return_type(minfo.return_val.type); ret_node->set_enable_return_value(true); ret_node->set_name(name); - undo_redo->add_do_method(script.ptr(), "add_node", name, script->get_available_id() + 1, ret_node, _get_available_pos(false, ofs + Vector2(500, 0))); + int nid = script->get_available_id() + 1; + undo_redo->add_do_method(script.ptr(), "add_node", nid, ret_node, _get_available_pos(false, ofs + Vector2(500, 0))); + undo_redo->add_undo_method(script.ptr(), "remove_node", nid); } undo_redo->add_undo_method(script.ptr(), "remove_function", name); @@ -3916,21 +3512,16 @@ void VisualScriptEditor::_selected_new_virtual_method(const String &p_text, cons } void VisualScriptEditor::_cancel_connect_node() { - // ensure the cancel is done + // Ensure the cancel is done. port_action_new_node = -1; } -int VisualScriptEditor::_create_new_node_from_name(const String &p_text, const Vector2 &p_point, const StringName &p_func) { - StringName func = default_func; - if (p_func != StringName()) { - func = p_func; - } - +int VisualScriptEditor::_create_new_node_from_name(const String &p_text, const Vector2 &p_point) { Ref<VisualScriptNode> vnode = VisualScriptLanguage::singleton->create_node_from_name(p_text); int new_id = script->get_available_id(); undo_redo->create_action(TTR("Add Node")); - undo_redo->add_do_method(script.ptr(), "add_node", func, new_id, vnode, p_point); - undo_redo->add_undo_method(script.ptr(), "remove_node", func, new_id); + undo_redo->add_do_method(script.ptr(), "add_node", new_id, vnode, p_point); + undo_redo->add_undo_method(script.ptr(), "remove_node", new_id); undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); undo_redo->commit_action(); @@ -3938,7 +3529,7 @@ int VisualScriptEditor::_create_new_node_from_name(const String &p_text, const V } void VisualScriptEditor::_default_value_changed() { - Ref<VisualScriptNode> vsn = script->get_node(_get_function_of_node(editing_id), editing_id); + Ref<VisualScriptNode> vsn = script->get_node(editing_id); if (vsn.is_null()) { return; } @@ -3953,7 +3544,7 @@ void VisualScriptEditor::_default_value_changed() { } void VisualScriptEditor::_default_value_edited(Node *p_button, int p_id, int p_input_port) { - Ref<VisualScriptNode> vsn = script->get_node(_get_function_of_node(p_id), p_id); + Ref<VisualScriptNode> vsn = script->get_node(p_id); if (vsn.is_null()) { return; } @@ -3972,15 +3563,15 @@ void VisualScriptEditor::_default_value_edited(Node *p_button, int p_id, int p_i if (pinfo.type == Variant::NODE_PATH) { Node *edited_scene = get_tree()->get_edited_scene_root(); - if (edited_scene) { // Fixing an old crash bug ( Visual Script Crashes on editing NodePath with an empty scene open) + if (edited_scene) { // Fixing an old crash bug ( Visual Script Crashes on editing NodePath with an empty scene open). Node *script_node = _find_script_node(edited_scene, edited_scene, script); if (script_node) { - //pick a node relative to the script, IF the script exists + // Pick a node relative to the script, IF the script exists. pinfo.hint = PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE; pinfo.hint_string = script_node->get_path(); } else { - //pick a path relative to edited scene + // Pick a path relative to edited scene. pinfo.hint = PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE; pinfo.hint_string = get_tree()->get_edited_scene_root()->get_path(); } @@ -4078,11 +3669,8 @@ void VisualScriptEditor::_graph_ofs_changed(const Vector2 &p_ofs) { updating_graph = true; - // Just use the default func for all the properties that need to be handled for drawing rather than adding to the Visual Script Class - if (script->has_function(default_func)) { - script->set_function_scroll(default_func, graph->get_scroll_ofs() / EDSCALE); - script->set_edited(true); - } + script->set_scroll(graph->get_scroll_ofs() / EDSCALE); + script->set_edited(true); updating_graph = false; } @@ -4090,10 +3678,7 @@ void VisualScriptEditor::_comment_node_resized(const Vector2 &p_new_size, int p_ if (updating_graph) { return; } - - StringName func = _get_function_of_node(p_node); - - Ref<VisualScriptComment> vsc = script->get_node(func, p_node); + Ref<VisualScriptComment> vsc = script->get_node(p_node); if (vsc.is_null()) { return; } @@ -4104,16 +3689,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; @@ -4131,8 +3723,7 @@ void VisualScriptEditor::_menu_option(int p_what) { if (gn) { if (gn->is_selected()) { int id = String(gn->get_name()).to_int(); - StringName func = _get_function_of_node(id); - Ref<VisualScriptNode> vsn = script->get_node(func, id); + Ref<VisualScriptNode> vsn = script->get_node(id); if (vsn.is_valid()) { vsn->set_breakpoint(!vsn->is_breakpoint()); reselect.push_back(gn->get_name()); @@ -4154,30 +3745,23 @@ void VisualScriptEditor::_menu_option(int p_what) { } break; case EDIT_COPY_NODES: case EDIT_CUT_NODES: { - if (!script->has_function(default_func)) { - break; - } - clipboard->nodes.clear(); clipboard->data_connections.clear(); clipboard->sequence_connections.clear(); - Set<String> funcs; 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()) { - int id = String(gn->get_name()).to_int(); - StringName func = _get_function_of_node(id); - Ref<VisualScriptNode> node = script->get_node(func, id); + int id = gn->get_name().operator String().to_int(); + Ref<VisualScriptNode> node = script->get_node(id); if (Object::cast_to<VisualScriptFunction>(*node)) { EditorNode::get_singleton()->show_warning(TTR("Can't copy the function node.")); return; } if (node.is_valid()) { clipboard->nodes[id] = node->duplicate(true); - clipboard->nodes_positions[id] = script->get_node_position(func, id); - funcs.insert(String(func)); + clipboard->nodes_positions[id] = script->get_node_position(id); } } } @@ -4187,25 +3771,21 @@ void VisualScriptEditor::_menu_option(int p_what) { break; } - for (Set<String>::Element *F = funcs.front(); F; F = F->next()) { - List<VisualScript::SequenceConnection> sequence_connections; - - script->get_sequence_connection_list(F->get(), &sequence_connections); + List<VisualScript::SequenceConnection> sequence_connections; + script->get_sequence_connection_list(&sequence_connections); - for (List<VisualScript::SequenceConnection>::Element *E = sequence_connections.front(); E; E = E->next()) { - if (clipboard->nodes.has(E->get().from_node) && clipboard->nodes.has(E->get().to_node)) { - clipboard->sequence_connections.insert(E->get()); - } + for (List<VisualScript::SequenceConnection>::Element *E = sequence_connections.front(); E; E = E->next()) { + if (clipboard->nodes.has(E->get().from_node) && clipboard->nodes.has(E->get().to_node)) { + clipboard->sequence_connections.insert(E->get()); } + } - List<VisualScript::DataConnection> data_connections; - - script->get_data_connection_list(F->get(), &data_connections); + List<VisualScript::DataConnection> data_connections; + script->get_data_connection_list(&data_connections); - for (List<VisualScript::DataConnection>::Element *E = data_connections.front(); E; E = E->next()) { - if (clipboard->nodes.has(E->get().from_node) && clipboard->nodes.has(E->get().to_node)) { - clipboard->data_connections.insert(E->get()); - } + for (List<VisualScript::DataConnection>::Element *E = data_connections.front(); E; E = E->next()) { + if (clipboard->nodes.has(E->get().from_node) && clipboard->nodes.has(E->get().to_node)) { + clipboard->data_connections.insert(E->get()); } } if (p_what == EDIT_CUT_NODES) { @@ -4214,10 +3794,6 @@ void VisualScriptEditor::_menu_option(int p_what) { } break; case EDIT_PASTE_NODES: { - if (!script->has_function(default_func)) { - break; - } - if (clipboard->nodes.is_empty()) { EditorNode::get_singleton()->show_warning(TTR("Clipboard is empty!")); break; @@ -4233,15 +3809,11 @@ void VisualScriptEditor::_menu_option(int p_what) { Set<Vector2> existing_positions; { - List<StringName> functions; - script->get_function_list(&functions); - for (List<StringName>::Element *F = functions.front(); F; F = F->next()) { - List<int> nodes; - script->get_node_list(F->get(), &nodes); - for (List<int>::Element *E = nodes.front(); E; E = E->next()) { - Vector2 pos = script->get_node_position(F->get(), E->get()).snapped(Vector2(2, 2)); - existing_positions.insert(pos); - } + List<int> nodes; + script->get_node_list(&nodes); + for (List<int>::Element *E = nodes.front(); E; E = E->next()) { + Vector2 pos = script->get_node_position(E->get()).snapped(Vector2(2, 2)); + existing_positions.insert(pos); } } @@ -4259,18 +3831,18 @@ void VisualScriptEditor::_menu_option(int p_what) { paste_pos += Vector2(20, 20) * EDSCALE; } - undo_redo->add_do_method(script.ptr(), "add_node", default_func, new_id, node, paste_pos); - undo_redo->add_undo_method(script.ptr(), "remove_node", default_func, new_id); + undo_redo->add_do_method(script.ptr(), "add_node", new_id, node, paste_pos); + undo_redo->add_undo_method(script.ptr(), "remove_node", new_id); } for (Set<VisualScript::SequenceConnection>::Element *E = clipboard->sequence_connections.front(); E; E = E->next()) { - undo_redo->add_do_method(script.ptr(), "sequence_connect", default_func, remap[E->get().from_node], E->get().from_output, remap[E->get().to_node]); - undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", default_func, remap[E->get().from_node], E->get().from_output, remap[E->get().to_node]); + undo_redo->add_do_method(script.ptr(), "sequence_connect", remap[E->get().from_node], E->get().from_output, remap[E->get().to_node]); + undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", remap[E->get().from_node], E->get().from_output, remap[E->get().to_node]); } for (Set<VisualScript::DataConnection>::Element *E = clipboard->data_connections.front(); E; E = E->next()) { - undo_redo->add_do_method(script.ptr(), "data_connect", default_func, remap[E->get().from_node], E->get().from_port, remap[E->get().to_node], E->get().to_port); - undo_redo->add_undo_method(script.ptr(), "data_disconnect", default_func, remap[E->get().from_node], E->get().from_port, remap[E->get().to_node], E->get().to_port); + undo_redo->add_do_method(script.ptr(), "data_connect", remap[E->get().from_node], E->get().from_port, remap[E->get().to_node], E->get().to_port); + undo_redo->add_undo_method(script.ptr(), "data_disconnect", remap[E->get().from_node], E->get().from_port, remap[E->get().to_node], E->get().to_port); } undo_redo->add_do_method(this, "_update_graph"); @@ -4287,7 +3859,7 @@ void VisualScriptEditor::_menu_option(int p_what) { } } break; case EDIT_CREATE_FUNCTION: { - StringName function = ""; + // Create Function. Map<int, Ref<VisualScriptNode>> nodes; Set<int> selections; for (int i = 0; i < graph->get_child_count(); i++) { @@ -4295,20 +3867,14 @@ void VisualScriptEditor::_menu_option(int p_what) { if (gn) { if (gn->is_selected()) { int id = String(gn->get_name()).to_int(); - StringName func = _get_function_of_node(id); - Ref<VisualScriptNode> node = script->get_node(func, id); + Ref<VisualScriptNode> node = script->get_node(id); if (Object::cast_to<VisualScriptFunction>(*node)) { EditorNode::get_singleton()->show_warning(TTR("Can't create function with a function node.")); return; } if (node.is_valid()) { - if (func != function && function != StringName("")) { - EditorNode::get_singleton()->show_warning(TTR("Can't create function of nodes from nodes of multiple functions.")); - return; - } nodes.insert(id, node); selections.insert(id); - function = func; } } } @@ -4327,7 +3893,7 @@ void VisualScriptEditor::_menu_option(int p_what) { int start_node = -1; Set<int> end_nodes; if (nodes.size() == 1) { - Ref<VisualScriptNode> nd = script->get_node(function, nodes.front()->key()); + Ref<VisualScriptNode> nd = script->get_node(nodes.front()->key()); if (nd.is_valid() && nd->has_input_sequence_port()) { start_node = nodes.front()->key(); } else { @@ -4336,29 +3902,29 @@ void VisualScriptEditor::_menu_option(int p_what) { } } else { List<VisualScript::SequenceConnection> seqs; - script->get_sequence_connection_list(function, &seqs); + script->get_sequence_connection_list(&seqs); if (seqs.size() == 0) { - // in case there are no sequence connections - // select the top most node cause that's probably how - // the user wants to connect the nodes + // In case there are no sequence connections, + // select the top most node cause that's probably how, + // the user wants to connect the nodes. int top_nd = -1; Vector2 top; for (Map<int, Ref<VisualScriptNode>>::Element *E = nodes.front(); E; E = E->next()) { - Ref<VisualScriptNode> nd = script->get_node(function, E->key()); + Ref<VisualScriptNode> nd = script->get_node(E->key()); if (nd.is_valid() && nd->has_input_sequence_port()) { if (top_nd < 0) { top_nd = E->key(); - top = script->get_node_position(function, top_nd); + top = script->get_node_position(top_nd); } - Vector2 pos = script->get_node_position(function, E->key()); + Vector2 pos = script->get_node_position(E->key()); if (top.y > pos.y) { top_nd = E->key(); top = pos; } } } - Ref<VisualScriptNode> nd = script->get_node(function, top_nd); + Ref<VisualScriptNode> nd = script->get_node(top_nd); if (nd.is_valid() && nd->has_input_sequence_port()) { start_node = top_nd; } else { @@ -4366,7 +3932,7 @@ void VisualScriptEditor::_menu_option(int p_what) { return; } } else { - // pick the node with input sequence + // Pick the node with input sequence. Set<int> nodes_from; Set<int> nodes_to; for (List<VisualScript::SequenceConnection>::Element *E = seqs.front(); E; E = E->next()) { @@ -4387,13 +3953,13 @@ void VisualScriptEditor::_menu_option(int p_what) { nodes_to.insert(E->get().to_node); } - // to use to add return nodes + // To use to add return nodes. _get_ends(start_node, seqs, selections, end_nodes); if (start_node == -1) { - // if we still don't have a start node then - // run through the nodes and select the first tree node - // ie node without any input sequence but output sequence + // If we still don't have a start node then, + // run through the nodes and select the first tree node, + // ie node without any input sequence but output sequence. for (Set<int>::Element *E = nodes_from.front(); E; E = E->next()) { if (!nodes_to.has(E->get())) { start_node = E->get(); @@ -4404,20 +3970,20 @@ void VisualScriptEditor::_menu_option(int p_what) { } if (start_node == -1) { - return; // this should not happen, but just in case something goes wrong + return; // This should not happen, but just in case something goes wrong. } List<Variant::Type> inputs; // input types List<Pair<int, int>> input_connections; { List<VisualScript::DataConnection> dats; - script->get_data_connection_list(function, &dats); + script->get_data_connection_list(&dats); for (List<VisualScript::DataConnection>::Element *E = dats.front(); E; E = E->next()) { if (nodes.has(E->get().from_node) && nodes.has(E->get().to_node)) { datamove.insert(E->get()); } else if (!nodes.has(E->get().from_node) && nodes.has(E->get().to_node)) { - // add all these as inputs for the Function - Ref<VisualScriptNode> node = script->get_node(function, E->get().to_node); + // Add all these as inputs for the Function. + Ref<VisualScriptNode> node = script->get_node(E->get().to_node); if (node.is_valid()) { dataext.insert(E->get()); PropertyInfo pi = node->get_input_value_port_info(E->get().to_port); @@ -4429,59 +3995,55 @@ void VisualScriptEditor::_menu_option(int p_what) { } } } - - String new_fn = _validate_name("new_function"); - - Vector2 ofs = _get_available_pos(false, script->get_node_position(function, start_node) - Vector2(80, 150)); - - Ref<VisualScriptFunction> func_node; - func_node.instance(); - func_node->set_name(new_fn); - - undo_redo->create_action(TTR("Create Function")); - - undo_redo->add_do_method(script.ptr(), "add_function", new_fn); int fn_id = script->get_available_id(); - undo_redo->add_do_method(script.ptr(), "add_node", new_fn, fn_id, func_node, ofs); - undo_redo->add_undo_method(script.ptr(), "remove_function", new_fn); - undo_redo->add_do_method(this, "_update_members"); - undo_redo->add_undo_method(this, "_update_members"); - undo_redo->add_do_method(this, "emit_signal", "edited_script_changed"); - undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed"); - - // Move the nodes + { + String new_fn = _validate_name("new_function"); - for (Map<int, Ref<VisualScriptNode>>::Element *E = nodes.front(); E; E = E->next()) { - undo_redo->add_do_method(script.ptr(), "remove_node", function, E->key()); - undo_redo->add_do_method(script.ptr(), "add_node", new_fn, E->key(), E->get(), script->get_node_position(function, E->key())); + Vector2 ofs = _get_available_pos(false, script->get_node_position(start_node) - Vector2(80, 150)); - // undo_redo->add_undo_method(script.ptr(), "remove_node", new_fn, E->key()); not needed cause we already remove the function :P - undo_redo->add_undo_method(script.ptr(), "add_node", function, E->key(), E->get(), script->get_node_position(function, E->key())); - } + Ref<VisualScriptFunction> func_node; + func_node.instance(); + func_node->set_name(new_fn); - for (Set<VisualScript::SequenceConnection>::Element *E = seqmove.front(); E; E = E->next()) { - undo_redo->add_do_method(script.ptr(), "sequence_connect", new_fn, E->get().from_node, E->get().from_output, E->get().to_node); - undo_redo->add_undo_method(script.ptr(), "sequence_connect", function, E->get().from_node, E->get().from_output, E->get().to_node); - } + undo_redo->create_action(TTR("Create Function")); - for (Set<VisualScript::DataConnection>::Element *E = datamove.front(); E; E = E->next()) { - undo_redo->add_do_method(script.ptr(), "data_connect", new_fn, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); - undo_redo->add_undo_method(script.ptr(), "data_connect", function, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); + undo_redo->add_do_method(script.ptr(), "add_function", new_fn, fn_id); + undo_redo->add_do_method(script.ptr(), "add_node", fn_id, func_node, ofs); + undo_redo->add_undo_method(script.ptr(), "remove_function", new_fn); + undo_redo->add_undo_method(script.ptr(), "remove_node", fn_id); + undo_redo->add_do_method(this, "_update_members"); + undo_redo->add_undo_method(this, "_update_members"); + undo_redo->add_do_method(this, "emit_signal", "edited_script_changed"); + undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed"); + // Might make the system more intelligent by checking port from info. + int i = 0; + List<Pair<int, int>>::Element *F = input_connections.front(); + for (List<Variant::Type>::Element *E = inputs.front(); E && F; E = E->next(), F = F->next()) { + func_node->add_argument(E->get(), "arg_" + String::num_int64(i), i); + undo_redo->add_do_method(script.ptr(), "data_connect", fn_id, i, F->get().first, F->get().second); + i++; // increment i + } + // Ensure Preview Selection is of newly created function node. + if (selections.size()) { + EditorNode::get_singleton()->push_item(func_node.ptr()); + } } + // Move the nodes. - // Add undo for external connections as well so that it's easier to revert back and forth - // these didn't require do methods as it's already handled internally by other do calls + // Handles reconnection of sequence connections on undo, start here in case of issues. for (Set<VisualScript::SequenceConnection>::Element *E = seqext.front(); E; E = E->next()) { - undo_redo->add_undo_method(script.ptr(), "sequence_connect", function, E->get().from_node, E->get().from_output, E->get().to_node); + undo_redo->add_do_method(script.ptr(), "sequence_disconnect", E->get().from_node, E->get().from_output, E->get().to_node); + undo_redo->add_undo_method(script.ptr(), "sequence_connect", E->get().from_node, E->get().from_output, E->get().to_node); } for (Set<VisualScript::DataConnection>::Element *E = dataext.front(); E; E = E->next()) { - undo_redo->add_undo_method(script.ptr(), "data_connect", function, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); + undo_redo->add_do_method(script.ptr(), "data_disconnect", E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); + undo_redo->add_undo_method(script.ptr(), "data_connect", E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); } - // I don't really think we need support for non sequenced functions at this moment - undo_redo->add_do_method(script.ptr(), "sequence_connect", new_fn, fn_id, 0, start_node); + // I don't really think we need support for non sequenced functions at this moment. + undo_redo->add_do_method(script.ptr(), "sequence_connect", fn_id, 0, start_node); - // end nodes are mapped to the return nodes with data connections if possible + // Could fail with the new changes, start here when searching for bugs in create function shortcut. int m = 1; for (Set<int>::Element *G = end_nodes.front(); G; G = G->next()) { Ref<VisualScriptReturn> ret_node; @@ -4489,36 +4051,27 @@ void VisualScriptEditor::_menu_option(int p_what) { int ret_id = fn_id + (m++); selections.insert(ret_id); - Vector2 ofsi = _get_available_pos(false, script->get_node_position(function, G->get()) + Vector2(80, -100)); - undo_redo->add_do_method(script.ptr(), "add_node", new_fn, ret_id, ret_node, ofsi); - undo_redo->add_undo_method(script.ptr(), "remove_node", new_fn, ret_id); + Vector2 ofsi = _get_available_pos(false, script->get_node_position(G->get()) + Vector2(80, -100)); + undo_redo->add_do_method(script.ptr(), "add_node", ret_id, ret_node, ofsi); + undo_redo->add_undo_method(script.ptr(), "remove_node", ret_id); - undo_redo->add_do_method(script.ptr(), "sequence_connect", new_fn, G->get(), 0, ret_id); - // add data outputs from each of the end_nodes - Ref<VisualScriptNode> vsn = script->get_node(function, G->get()); + undo_redo->add_do_method(script.ptr(), "sequence_connect", G->get(), 0, ret_id); + // Add data outputs from each of the end_nodes. + Ref<VisualScriptNode> vsn = script->get_node(G->get()); if (vsn.is_valid() && vsn->get_output_value_port_count() > 0) { ret_node->set_enable_return_value(true); - // use the zeroth data port cause that's the likely one that is planned to be used + // Use the zeroth data port cause that's the likely one that is planned to be used. ret_node->set_return_type(vsn->get_output_value_port_info(0).type); - undo_redo->add_do_method(script.ptr(), "data_connect", new_fn, G->get(), 0, ret_id, 0); + undo_redo->add_do_method(script.ptr(), "data_connect", G->get(), 0, ret_id, 0); } } - // * might make the system more intelligent by checking port from info. - int i = 0; - List<Pair<int, int>>::Element *F = input_connections.front(); - for (List<Variant::Type>::Element *E = inputs.front(); E && F; E = E->next(), F = F->next()) { - func_node->add_argument(E->get(), "arg_" + String::num_int64(i), i); - undo_redo->add_do_method(script.ptr(), "data_connect", new_fn, fn_id, i, F->get().first, F->get().second); - i++; // increment i - } - undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); undo_redo->commit_action(); - // make sure all Nodes get marked for selection so that they can be moved together + // Make sure all Nodes get marked for selection so that they can be moved together. selections.insert(fn_id); for (int k = 0; k < graph->get_child_count(); k++) { GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(k)); @@ -4528,11 +4081,6 @@ void VisualScriptEditor::_menu_option(int p_what) { } } - // Ensure Preview Selection is of newly created function node - if (selections.size()) { - EditorNode::get_singleton()->push_item(func_node.ptr()); - } - } break; case REFRESH_GRAPH: { _update_graph(); @@ -4540,16 +4088,16 @@ void VisualScriptEditor::_menu_option(int p_what) { } } -// this is likely going to be very slow and I am not sure if I should keep it -// but I hope that it will not be a problem considering that we won't be creating functions so frequently -// and cyclic connections would be a problem but hopefully we won't let them get to this point +// This is likely going to be very slow and I am not sure if I should keep it, +// but I hope that it will not be a problem considering that we won't be creating functions so frequently, +// and cyclic connections would be a problem but hopefully we won't let them get to this point. void VisualScriptEditor::_get_ends(int p_node, const List<VisualScript::SequenceConnection> &p_seqs, const Set<int> &p_selected, Set<int> &r_end_nodes) { for (const List<VisualScript::SequenceConnection>::Element *E = p_seqs.front(); E; E = E->next()) { int from = E->get().from_node; int to = E->get().to_node; if (from == p_node && p_selected.has(to)) { - // this is an interior connection move forward to the to node + // This is an interior connection move forward to the to node. _get_ends(to, p_seqs, p_selected, r_end_nodes); } else if (from == p_node && !p_selected.has(to)) { r_end_nodes.insert(from); @@ -4609,34 +4157,29 @@ void VisualScriptEditor::_member_option(int p_option) { switch (member_type) { case MEMBER_FUNCTION: { if (p_option == MEMBER_REMOVE) { - //delete the function + // Delete the function. String name = member_name; - + List<String> lst; + int fn_node = script->get_function_node_id(name); undo_redo->create_action(TTR("Remove Function")); undo_redo->add_do_method(script.ptr(), "remove_function", name); - undo_redo->add_undo_method(script.ptr(), "add_function", name); - List<int> nodes; - script->get_node_list(name, &nodes); - for (List<int>::Element *E = nodes.front(); E; E = E->next()) { - undo_redo->add_undo_method(script.ptr(), "add_node", name, E->get(), script->get_node(name, E->get()), script->get_node_position(name, E->get())); - } - - List<VisualScript::SequenceConnection> seq_connections; - - script->get_sequence_connection_list(name, &seq_connections); - - for (List<VisualScript::SequenceConnection>::Element *E = seq_connections.front(); E; E = E->next()) { - undo_redo->add_undo_method(script.ptr(), "sequence_connect", name, E->get().from_node, E->get().from_output, E->get().to_node); + undo_redo->add_do_method(script.ptr(), "remove_node", fn_node); + undo_redo->add_undo_method(script.ptr(), "add_function", name, fn_node); + undo_redo->add_undo_method(script.ptr(), "add_node", fn_node, script->get_node(fn_node), script->get_node_position(fn_node)); + List<VisualScript::SequenceConnection> seqcons; + script->get_sequence_connection_list(&seqcons); + for (const List<VisualScript::SequenceConnection>::Element *E = seqcons.front(); E; E = E->next()) { + if (E->get().from_node == fn_node) { + undo_redo->add_undo_method(script.ptr(), "sequence_connect", fn_node, E->get().from_output, E->get().to_node); + } } - - List<VisualScript::DataConnection> data_connections; - - script->get_data_connection_list(name, &data_connections); - - for (List<VisualScript::DataConnection>::Element *E = data_connections.front(); E; E = E->next()) { - undo_redo->add_undo_method(script.ptr(), "data_connect", name, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); + List<VisualScript::DataConnection> datcons; + script->get_data_connection_list(&datcons); + for (const List<VisualScript::DataConnection>::Element *E = datcons.front(); E; E = E->next()) { + if (E->get().from_node == fn_node) { + undo_redo->add_undo_method(script.ptr(), "data_connect", fn_node, E->get().from_port, E->get().to_node, E->get().to_port); + } } - undo_redo->add_do_method(this, "_update_members"); undo_redo->add_undo_method(this, "_update_members"); undo_redo->add_do_method(this, "_update_graph"); @@ -4794,6 +4337,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)); diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h index a788c00c61..bb6f194286 100644 --- a/modules/visual_script/visual_script_editor.h +++ b/modules/visual_script/visual_script_editor.h @@ -136,8 +136,6 @@ class VisualScriptEditor : public ScriptEditorBase { }; HashMap<StringName, Ref<StyleBox>> node_styles; - StringName edited_func; - StringName default_func; void _update_graph_connections(); void _update_graph(int p_only_id = -1); @@ -176,7 +174,7 @@ class VisualScriptEditor : public ScriptEditorBase { Vector2 mouse_up_position; - void _port_action_menu(int p_option, const StringName &p_func); + void _port_action_menu(int p_option); void connect_data(Ref<VisualScriptNode> vnode_old, Ref<VisualScriptNode> vnode, int new_id); @@ -184,13 +182,13 @@ class VisualScriptEditor : public ScriptEditorBase { void connect_seq(Ref<VisualScriptNode> vnode_old, Ref<VisualScriptNode> vnode_new, int new_id); void _cancel_connect_node(); - int _create_new_node_from_name(const String &p_text, const Vector2 &p_point, const StringName &p_func = StringName()); + int _create_new_node_from_name(const String &p_text, const Vector2 &p_point); void _selected_new_virtual_method(const String &p_text, const String &p_category, const bool p_connecting); int error_line; void _node_selected(Node *p_node); - void _center_on_node(const StringName &p_func, int p_id); + void _center_on_node(int p_id); void _node_filter_changed(const String &p_text); void _change_base_type_callback(); @@ -201,7 +199,7 @@ class VisualScriptEditor : public ScriptEditorBase { void _begin_node_move(); void _end_node_move(); - void _move_node(const StringName &p_func, int p_id, const Vector2 &p_to); + void _move_node(int p_id, const Vector2 &p_to); void _get_ends(int p_node, const List<VisualScript::SequenceConnection> &p_seqs, const Set<int> &p_selected, Set<int> &r_end_nodes); @@ -211,7 +209,7 @@ class VisualScriptEditor : public ScriptEditorBase { void _graph_disconnected(const String &p_from, int p_from_slot, const String &p_to, int p_to_slot); void _graph_connect_to_empty(const String &p_from, int p_from_slot, const Vector2 &p_release_pos); - void _node_ports_changed(const String &p_func, int p_id); + void _node_ports_changed(int p_id); void _node_create(); void _update_available_nodes(); @@ -228,10 +226,8 @@ class VisualScriptEditor : public ScriptEditorBase { void _port_name_focus_out(const Node *p_name_box, int p_id, int p_port, bool is_input); Vector2 _get_available_pos(bool centered = true, Vector2 ofs = Vector2()) const; - StringName _get_function_of_node(int p_id) const; - void _move_nodes_with_rescan(const StringName &p_func_from, const StringName &p_func_to, int p_id); - bool node_has_sequence_connections(const StringName &p_func, int p_id); + bool node_has_sequence_connections(int p_id); void _generic_search(String p_base_type = "", Vector2 pos = Vector2(), bool node_centered = false); diff --git a/modules/visual_script/visual_script_expression.cpp b/modules/visual_script/visual_script_expression.cpp index 9596fda95c..469367ab59 100644 --- a/modules/visual_script/visual_script_expression.cpp +++ b/modules/visual_script/visual_script_expression.cpp @@ -1507,12 +1507,6 @@ VisualScriptNodeInstance *VisualScriptExpression::instance(VisualScriptInstance } 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..bbf76cef3b 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); 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/SCsub b/modules/webxr/SCsub new file mode 100644 index 0000000000..0a96af0811 --- /dev/null +++ b/modules/webxr/SCsub @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +Import("env") +Import("env_modules") + +if env["platform"] == "javascript": + env.AddJSLibraries(["native/library_godot_webxr.js"]) + env.AddJSExterns(["native/webxr.externs.js"]) + +env_webxr = env_modules.Clone() +env_webxr.add_source_files(env.modules_sources, "*.cpp") diff --git a/modules/webxr/config.py b/modules/webxr/config.py new file mode 100644 index 0000000000..9efebed4e6 --- /dev/null +++ b/modules/webxr/config.py @@ -0,0 +1,14 @@ +def can_build(env, platform): + return True + + +def configure(env): + pass + + +def get_doc_classes(): + return ["WebXRInterface"] + + +def get_doc_path(): + return "doc_classes" diff --git a/modules/webxr/doc_classes/WebXRInterface.xml b/modules/webxr/doc_classes/WebXRInterface.xml new file mode 100644 index 0000000000..2407d44496 --- /dev/null +++ b/modules/webxr/doc_classes/WebXRInterface.xml @@ -0,0 +1,257 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="WebXRInterface" inherits="XRInterface" version="4.0"> + <brief_description> + AR/VR interface using WebXR. + </brief_description> + <description> + WebXR is an open standard that allows creating VR and AR applications that run in the web browser. + As such, this interface is only available when running in an HTML5 export. + WebXR supports a wide range of devices, from the very capable (like Valve Index, HTC Vive, Oculus Rift and Quest) down to the much less capable (like Google Cardboard, Oculus Go, GearVR, or plain smartphones). + 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] + extends Node3D + + var webxr_interface + var vr_supported = false + + 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") + + 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") + + # 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 _webxr_session_supported(session_mode, supported): + if session_mode == 'immersive-vr': + vr_supported = supported + + func _on_Button_pressed(): + if not vr_supported: + OS.alert("Your browser doesn't support VR") + 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' + + # 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_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_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]. + - Using [method Node._unhandled_input] and [InputEventJoypadButton] or [InputEventJoypadMotion]. This works the same as normal joypads, except the [member InputEvent.device] starts at 100, so the left controller is 100 and the right controller is 101, and the button codes are also defined by [url=https://immersive-web.github.io/webxr-gamepads-module/#xr-standard-gamepad-mapping]Section 3.3 of the WebXR Gamepads Module[/url]. + - Using the [signal select], [signal squeeze] and related signals. This method will work for both advanced VR controllers, and non-traditional "controllers" like a tap on the screen, a spoken voice command or a button press on the device itself. The [code]controller_id[/code] passed to these signals is the same id as used in [member XRController3D.controller_id]. + You can use one or all of these methods to allow your game or app to support a wider or narrower set of devices and input methods, or to allow more advanced interations with more advanced devices. + </description> + <tutorials> + <link title="How to make a VR game for WebXR with Godot">https://www.snopekgames.com/blog/2020/how-make-vr-game-webxr-godot</link> + </tutorials> + <methods> + <method name="get_controller" qualifiers="const"> + <return type="XRPositionalTracker"> + </return> + <argument index="0" name="controller_id" type="int"> + </argument> + <description> + Gets an [XRPositionalTracker] for the given [code]controller_id[/code]. + In the context of WebXR, a "controller" can be an advanced VR controller like the Oculus Touch or Index controllers, or even a tap on the screen, a spoken voice command or a button press on the device itself. When a non-traditional controller is used, interpret the position and orientation of the [XRPositionalTracker] as a ray pointing at the object the user wishes to interact with. + Use this method to get information about the controller that triggered one of these signals: + - [signal selectstart] + - [signal select] + - [signal selectend] + - [signal squeezestart] + - [signal squeeze] + - [signal squeezestart] + </description> + </method> + <method name="is_session_supported"> + <return type="void"> + </return> + <argument index="0" name="session_mode" type="String"> + </argument> + <description> + Checks if the given [code]session_mode[/code] is supported by the user's browser. + Possible values come from [url=https://developer.mozilla.org/en-US/docs/Web/API/XRSessionMode]WebXR's XRSessionMode[/url], including: [code]"immersive-vr"[/code], [code]"immersive-ar"[/code], and [code]"inline"[/code]. + This method returns nothing, instead it emits the [signal session_supported] signal with the result. + </description> + </method> + </methods> + <members> + <member name="bounds_geometry" type="PackedVector3Array" setter="" getter="get_bounds_geometry"> + The vertices of a polygon which defines the boundaries of the user's play area. + This will only be available if [member reference_space_type] is [code]"bounded-floor"[/code] and only on certain browsers and devices that support it. + The [signal reference_space_reset] signal may indicate when this changes. + </member> + <member name="optional_features" type="String" setter="set_optional_features" getter="get_optional_features"> + A comma-seperated list of optional features used by [method XRInterface.initialize] when setting up the WebXR session. + If a user's browser or device doesn't support one of the given features, initialization will continue, but you won't be able to use the requested feature. + This doesn't have any effect on the interface when already initialized. + Possible values come from [url=https://developer.mozilla.org/en-US/docs/Web/API/XRReferenceSpaceType]WebXR's XRReferenceSpaceType[/url]. If you want to use a particular reference space type, it must be listed in either [member required_features] or [member optional_features]. + </member> + <member name="reference_space_type" type="String" setter="" getter="get_reference_space_type"> + The reference space type (from the list of requested types set in the [member requested_reference_space_types] property), that was ultimately used by [method XRInterface.initialize] when setting up the WebXR session. + Possible values come from [url=https://developer.mozilla.org/en-US/docs/Web/API/XRReferenceSpaceType]WebXR's XRReferenceSpaceType[/url]. If you want to use a particular reference space type, it must be listed in either [member required_features] or [member optional_features]. + </member> + <member name="requested_reference_space_types" type="String" setter="set_requested_reference_space_types" getter="get_requested_reference_space_types"> + A comma-seperated list of reference space types used by [method XRInterface.initialize] when setting up the WebXR session. + The reference space types are requested in order, and the first on supported by the users device or browser will be used. The [member reference_space_type] property contains the reference space type that was ultimately used. + This doesn't have any effect on the interface when already initialized. + Possible values come from [url=https://developer.mozilla.org/en-US/docs/Web/API/XRReferenceSpaceType]WebXR's XRReferenceSpaceType[/url]. If you want to use a particular reference space type, it must be listed in either [member required_features] or [member optional_features]. + </member> + <member name="required_features" type="String" setter="set_required_features" getter="get_required_features"> + A comma-seperated list of required features used by [method XRInterface.initialize] when setting up the WebXR session. + If a user's browser or device doesn't support one of the given features, initialization will fail and [signal session_failed] will be emitted. + This doesn't have any effect on the interface when already initialized. + Possible values come from [url=https://developer.mozilla.org/en-US/docs/Web/API/XRReferenceSpaceType]WebXR's XRReferenceSpaceType[/url]. If you want to use a particular reference space type, it must be listed in either [member required_features] or [member optional_features]. + </member> + <member name="session_mode" type="String" setter="set_session_mode" getter="get_session_mode"> + The session mode used by [method XRInterface.initialize] when setting up the WebXR session. + This doesn't have any effect on the interface when already initialized. + Possible values come from [url=https://developer.mozilla.org/en-US/docs/Web/API/XRSessionMode]WebXR's XRSessionMode[/url], including: [code]"immersive-vr"[/code], [code]"immersive-ar"[/code], and [code]"inline"[/code]. + </member> + <member name="visibility_state" type="String" setter="" getter="get_visibility_state"> + Indicates if the WebXR session's imagery is visible to the user. + Possible values come from [url=https://developer.mozilla.org/en-US/docs/Web/API/XRVisibilityState]WebXR's XRVisibilityState[/url], including [code]"hidden"[/code], [code]"visible"[/code], and [code]"visible-blurred"[/code]. + </member> + </members> + <signals> + <signal name="reference_space_reset"> + <description> + Emitted to indicate that the reference space has been reset or reconfigured. + When (or whether) this is emitted depends on the user's browser or device, but may include when the user has changed the dimensions of their play space (which you may be able to access via [member bounds_geometry]) or pressed/held a button to recenter their position. + See [url=https://developer.mozilla.org/en-US/docs/Web/API/XRReferenceSpace/reset_event]WebXR's XRReferenceSpace reset event[/url] for more information. + </description> + </signal> + <signal name="select"> + <argument index="0" name="controller_id" type="int"> + </argument> + <description> + Emitted after one of the "controllers" has finished its "primary action". + Use [method get_controller] to get more information about the controller. + </description> + </signal> + <signal name="selectend"> + <argument index="0" name="controller_id" type="int"> + </argument> + <description> + Emitted when one of the "controllers" has finished its "primary action". + Use [method get_controller] to get more information about the controller. + </description> + </signal> + <signal name="selectstart"> + <argument index="0" name="controller_id" type="int"> + </argument> + <description> + Emitted when one of the "controllers" has started its "primary action". + Use [method get_controller] to get more information about the controller. + </description> + </signal> + <signal name="session_ended"> + <description> + Emitted when the user ends the WebXR session (which can be done using UI from the browser or device). + At this point, you should do [code]get_viewport().xr = false[/code] to instruct Godot to resume rendering to the screen. + </description> + </signal> + <signal name="session_failed"> + <argument index="0" name="message" type="String"> + </argument> + <description> + Emitted by [method XRInterface.initialize] if the session fails to start. + [code]message[/code] may optionally contain an error message from WebXR, or an empty string if no message is available. + </description> + </signal> + <signal name="session_started"> + <description> + Emitted by [method XRInterface.initialize] if the session is successfully started. + At this point, it's safe to do [code]get_viewport().xr = true[/code] to instruct Godot to start rendering to the AR/VR device. + </description> + </signal> + <signal name="session_supported"> + <argument index="0" name="session_mode" type="String"> + </argument> + <argument index="1" name="supported" type="bool"> + </argument> + <description> + Emitted by [method is_session_supported] to indicate if the given [code]session_mode[/code] is supported or not. + </description> + </signal> + <signal name="squeeze"> + <argument index="0" name="controller_id" type="int"> + </argument> + <description> + Emitted after one of the "controllers" has finished its "primary squeeze action". + Use [method get_controller] to get more information about the controller. + </description> + </signal> + <signal name="squeezeend"> + <argument index="0" name="controller_id" type="int"> + </argument> + <description> + Emitted when one of the "controllers" has finished its "primary squeeze action". + Use [method get_controller] to get more information about the controller. + </description> + </signal> + <signal name="squeezestart"> + <argument index="0" name="controller_id" type="int"> + </argument> + <description> + Emitted when one of the "controllers" has started its "primary squeeze action". + Use [method get_controller] to get more information about the controller. + </description> + </signal> + <signal name="visibility_state_changed"> + <description> + Emitted when [member visibility_state] has changed. + </description> + </signal> + </signals> + <constants> + </constants> +</class> diff --git a/drivers/windows/thread_windows.h b/modules/webxr/godot_webxr.h index 3801bddc2c..41a690f473 100644 --- a/drivers/windows/thread_windows.h +++ b/modules/webxr/godot_webxr.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* thread_windows.h */ +/* godot_webxr.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,40 +28,58 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef THREAD_WINDOWS_H -#define THREAD_WINDOWS_H +#ifndef GODOT_WEBXR_H +#define GODOT_WEBXR_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; +#ifdef __cplusplus +extern "C" { +#endif - static Thread *create_thread_windows(); +#include "stddef.h" - static DWORD WINAPI thread_callback(LPVOID userdata); +typedef void (*GodotWebXRSupportedCallback)(char *p_session_mode, int p_supported); +typedef void (*GodotWebXRStartedCallback)(char *p_reference_space_type); +typedef void (*GodotWebXREndedCallback)(); +typedef void (*GodotWebXRFailedCallback)(char *p_message); +typedef void (*GodotWebXRControllerCallback)(); +typedef void (*GodotWebXRInputEventCallback)(char *p_signal_name, int p_controller_id); +typedef void (*GodotWebXRSimpleEventCallback)(char *p_signal_name); - 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); +extern int godot_webxr_is_supported(); +extern void godot_webxr_is_session_supported(const char *p_session_mode, GodotWebXRSupportedCallback p_callback); - ThreadWindows() {} +extern void godot_webxr_initialize( + const char *p_session_mode, + const char *p_required_features, + const char *p_optional_features, + const char *p_requested_reference_space_types, + GodotWebXRStartedCallback p_on_session_started, + GodotWebXREndedCallback p_on_session_ended, + GodotWebXRFailedCallback p_on_session_failed, + GodotWebXRControllerCallback p_on_controller_changed, + GodotWebXRInputEventCallback p_on_input_event, + GodotWebXRSimpleEventCallback p_on_simple_event); +extern void godot_webxr_uninitialize(); -public: - virtual ID get_id() const; +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); +extern int godot_webxr_get_external_texture_for_eye(int p_eye); +extern void godot_webxr_commit_for_eye(int p_eye); - static void make_default(); +extern void godot_webxr_sample_controller_data(); +extern int godot_webxr_get_controller_count(); +extern int godot_webxr_is_controller_connected(int p_controller); +extern float *godot_webxr_get_controller_transform(int p_controller); +extern int *godot_webxr_get_controller_buttons(int p_controller); +extern int *godot_webxr_get_controller_axes(int p_controller); - ~ThreadWindows() {} -}; +extern char *godot_webxr_get_visibility_state(); +extern int *godot_webxr_get_bounds_geometry(); +#ifdef __cplusplus +} #endif -#endif +#endif /* GODOT_WEBXR_H */ diff --git a/modules/webxr/native/library_godot_webxr.js b/modules/webxr/native/library_godot_webxr.js new file mode 100644 index 0000000000..8e9ef8a73c --- /dev/null +++ b/modules/webxr/native/library_godot_webxr.js @@ -0,0 +1,672 @@ +/*************************************************************************/ +/* library_godot_webxr.js */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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. */ +/*************************************************************************/ +const GodotWebXR = { + $GodotWebXR__deps: ['$Browser', '$GL', '$GodotRuntime'], + $GodotWebXR: { + gl: null, + + texture_ids: [null, null], + textures: [null, null], + + session: null, + space: null, + frame: null, + pose: null, + + // Monkey-patch the requestAnimationFrame() used by Emscripten for the main + // loop, so that we can swap it out for XRSession.requestAnimationFrame() + // when an XR session is started. + orig_requestAnimationFrame: null, + requestAnimationFrame: (callback) => { + if (GodotWebXR.session && GodotWebXR.space) { + const onFrame = function (time, frame) { + GodotWebXR.frame = frame; + GodotWebXR.pose = frame.getViewerPose(GodotWebXR.space); + callback(time); + GodotWebXR.frame = null; + GodotWebXR.pose = null; + }; + GodotWebXR.session.requestAnimationFrame(onFrame); + } else { + GodotWebXR.orig_requestAnimationFrame(callback); + } + }, + monkeyPatchRequestAnimationFrame: (enable) => { + if (GodotWebXR.orig_requestAnimationFrame === null) { + GodotWebXR.orig_requestAnimationFrame = Browser.requestAnimationFrame; + } + Browser.requestAnimationFrame = enable + ? GodotWebXR.requestAnimationFrame : GodotWebXR.orig_requestAnimationFrame; + }, + pauseResumeMainLoop: () => { + // Once both GodotWebXR.session and GodotWebXR.space are set or + // unset, our monkey-patched requestAnimationFrame() should be + // enabled or disabled. When using the WebXR API Emulator, this + // gets picked up automatically, however, in the Oculus Browser + // on the Quest, we need to pause and resume the main loop. + Browser.pauseAsyncCallbacks(); + Browser.mainLoop.pause(); + window.setTimeout(function () { + Browser.resumeAsyncCallbacks(); + Browser.mainLoop.resume(); + }, 0); + }, + + // Some custom WebGL code for blitting our eye textures to the + // framebuffer we get from WebXR. + shaderProgram: null, + programInfo: null, + buffer: null, + // Vertex shader source. + vsSource: ` + const vec2 scale = vec2(0.5, 0.5); + attribute vec4 aVertexPosition; + + varying highp vec2 vTextureCoord; + + void main () { + gl_Position = aVertexPosition; + vTextureCoord = aVertexPosition.xy * scale + scale; + } + `, + // Fragment shader source. + fsSource: ` + varying highp vec2 vTextureCoord; + + uniform sampler2D uSampler; + + void main() { + gl_FragColor = texture2D(uSampler, vTextureCoord); + } + `, + + initShaderProgram: (gl, vsSource, fsSource) => { + const vertexShader = GodotWebXR.loadShader(gl, gl.VERTEX_SHADER, vsSource); + const fragmentShader = GodotWebXR.loadShader(gl, gl.FRAGMENT_SHADER, fsSource); + + const shaderProgram = gl.createProgram(); + gl.attachShader(shaderProgram, vertexShader); + gl.attachShader(shaderProgram, fragmentShader); + gl.linkProgram(shaderProgram); + + if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { + GodotRuntime.error(`Unable to initialize the shader program: ${gl.getProgramInfoLog(shaderProgram)}`); + return null; + } + + return shaderProgram; + }, + loadShader: (gl, type, source) => { + const shader = gl.createShader(type); + gl.shaderSource(shader, source); + gl.compileShader(shader); + + if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { + GodotRuntime.error(`An error occurred compiling the shader: ${gl.getShaderInfoLog(shader)}`); + gl.deleteShader(shader); + return null; + } + + return shader; + }, + initBuffer: (gl) => { + const positionBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); + const positions = [ + -1.0, -1.0, + 1.0, -1.0, + -1.0, 1.0, + 1.0, 1.0, + ]; + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW); + return positionBuffer; + }, + blitTexture: (gl, texture) => { + if (GodotWebXR.shaderProgram === null) { + GodotWebXR.shaderProgram = GodotWebXR.initShaderProgram(gl, GodotWebXR.vsSource, GodotWebXR.fsSource); + GodotWebXR.programInfo = { + program: GodotWebXR.shaderProgram, + attribLocations: { + vertexPosition: gl.getAttribLocation(GodotWebXR.shaderProgram, 'aVertexPosition'), + }, + uniformLocations: { + uSampler: gl.getUniformLocation(GodotWebXR.shaderProgram, 'uSampler'), + }, + }; + GodotWebXR.buffer = GodotWebXR.initBuffer(gl); + } + + const orig_program = gl.getParameter(gl.CURRENT_PROGRAM); + gl.useProgram(GodotWebXR.shaderProgram); + + gl.bindBuffer(gl.ARRAY_BUFFER, GodotWebXR.buffer); + gl.vertexAttribPointer(GodotWebXR.programInfo.attribLocations.vertexPosition, 2, gl.FLOAT, false, 0, 0); + gl.enableVertexAttribArray(GodotWebXR.programInfo.attribLocations.vertexPosition); + + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.uniform1i(GodotWebXR.programInfo.uniformLocations.uSampler, 0); + + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + + // Restore state. + gl.bindTexture(gl.TEXTURE_2D, null); + gl.disableVertexAttribArray(GodotWebXR.programInfo.attribLocations.vertexPosition); + gl.bindBuffer(gl.ARRAY_BUFFER, null); + gl.useProgram(orig_program); + }, + + // Holds the controllers list between function calls. + controllers: [], + + // Updates controllers array, where the left hand (or sole tracker) is + // the first element, and the right hand is the second element, and any + // others placed at the 3rd position and up. + sampleControllers: () => { + if (!GodotWebXR.session || !GodotWebXR.frame) { + return; + } + + let other_index = 2; + const controllers = []; + GodotWebXR.session.inputSources.forEach((input_source) => { + if (input_source.targetRayMode === 'tracked-pointer') { + if (input_source.handedness === 'right') { + controllers[1] = input_source; + } else if (input_source.handedness === 'left' || !controllers[0]) { + controllers[0] = input_source; + } + } else { + controllers[other_index++] = input_source; + } + }); + GodotWebXR.controllers = controllers; + }, + + getControllerId: (input_source) => GodotWebXR.controllers.indexOf(input_source), + }, + + godot_webxr_is_supported__proxy: 'sync', + godot_webxr_is_supported__sig: 'i', + godot_webxr_is_supported: function () { + return !!navigator.xr; + }, + + godot_webxr_is_session_supported__proxy: 'sync', + godot_webxr_is_session_supported__sig: 'vii', + godot_webxr_is_session_supported: function (p_session_mode, p_callback) { + const session_mode = GodotRuntime.parseString(p_session_mode); + const cb = GodotRuntime.get_func(p_callback); + if (navigator.xr) { + navigator.xr.isSessionSupported(session_mode).then(function (supported) { + const c_str = GodotRuntime.allocString(session_mode); + cb(c_str, supported ? 1 : 0); + GodotRuntime.free(c_str); + }); + } else { + const c_str = GodotRuntime.allocString(session_mode); + cb(c_str, 0); + GodotRuntime.free(c_str); + } + }, + + godot_webxr_initialize__deps: ['emscripten_webgl_get_current_context'], + godot_webxr_initialize__proxy: 'sync', + godot_webxr_initialize__sig: 'viiiiiiiiii', + godot_webxr_initialize: function (p_session_mode, p_required_features, p_optional_features, p_requested_reference_spaces, p_on_session_started, p_on_session_ended, p_on_session_failed, p_on_controller_changed, p_on_input_event, p_on_simple_event) { + GodotWebXR.monkeyPatchRequestAnimationFrame(true); + + const session_mode = GodotRuntime.parseString(p_session_mode); + const required_features = GodotRuntime.parseString(p_required_features).split(',').map((s) => s.trim()).filter((s) => s !== ''); + const optional_features = GodotRuntime.parseString(p_optional_features).split(',').map((s) => s.trim()).filter((s) => s !== ''); + const requested_reference_space_types = GodotRuntime.parseString(p_requested_reference_spaces).split(',').map((s) => s.trim()); + const onstarted = GodotRuntime.get_func(p_on_session_started); + const onended = GodotRuntime.get_func(p_on_session_ended); + const onfailed = GodotRuntime.get_func(p_on_session_failed); + const oncontroller = GodotRuntime.get_func(p_on_controller_changed); + const oninputevent = GodotRuntime.get_func(p_on_input_event); + const onsimpleevent = GodotRuntime.get_func(p_on_simple_event); + + const session_init = {}; + if (required_features.length > 0) { + session_init['requiredFeatures'] = required_features; + } + if (optional_features.length > 0) { + session_init['optionalFeatures'] = optional_features; + } + + navigator.xr.requestSession(session_mode, session_init).then(function (session) { + GodotWebXR.session = session; + + session.addEventListener('end', function (evt) { + onended(); + }); + + session.addEventListener('inputsourceschange', function (evt) { + let controller_changed = false; + [evt.added, evt.removed].forEach((lst) => { + lst.forEach((input_source) => { + if (input_source.targetRayMode === 'tracked-pointer') { + controller_changed = true; + } + }); + }); + if (controller_changed) { + oncontroller(); + } + }); + + ['selectstart', 'select', 'selectend', 'squeezestart', 'squeeze', 'squeezeend'].forEach((input_event) => { + session.addEventListener(input_event, function (evt) { + const c_str = GodotRuntime.allocString(input_event); + oninputevent(c_str, GodotWebXR.getControllerId(evt.inputSource)); + GodotRuntime.free(c_str); + }); + }); + + session.addEventListener('visibilitychange', function (evt) { + const c_str = GodotRuntime.allocString('visibility_state_changed'); + onsimpleevent(c_str); + GodotRuntime.free(c_str); + }); + + const gl_context_handle = _emscripten_webgl_get_current_context(); // eslint-disable-line no-undef + const gl = GL.getContext(gl_context_handle).GLctx; + GodotWebXR.gl = gl; + + gl.makeXRCompatible().then(function () { + session.updateRenderState({ + baseLayer: new XRWebGLLayer(session, gl), + }); + + function onReferenceSpaceSuccess(reference_space, reference_space_type) { + GodotWebXR.space = reference_space; + + // Using reference_space.addEventListener() crashes when + // using the polyfill with the WebXR Emulator extension, + // so we set the event property instead. + reference_space.onreset = function (evt) { + const c_str = GodotRuntime.allocString('reference_space_reset'); + onsimpleevent(c_str); + GodotRuntime.free(c_str); + }; + + // Now that both GodotWebXR.session and GodotWebXR.space are + // set, we need to pause and resume the main loop for the XR + // main loop to kick in. + GodotWebXR.pauseResumeMainLoop(); + + // Call in setTimeout() so that errors in the onstarted() + // callback don't bubble up here and cause Godot to try the + // next reference space. + window.setTimeout(function () { + const c_str = GodotRuntime.allocString(reference_space_type); + onstarted(c_str); + GodotRuntime.free(c_str); + }, 0); + } + + function requestReferenceSpace() { + const reference_space_type = requested_reference_space_types.shift(); + session.requestReferenceSpace(reference_space_type) + .then((refSpace) => { + onReferenceSpaceSuccess(refSpace, reference_space_type); + }) + .catch(() => { + if (requested_reference_space_types.length === 0) { + const c_str = GodotRuntime.allocString('Unable to get any of the requested reference space types'); + onfailed(c_str); + GodotRuntime.free(c_str); + } else { + requestReferenceSpace(); + } + }); + } + + requestReferenceSpace(); + }).catch(function (error) { + const c_str = GodotRuntime.allocString(`Unable to make WebGL context compatible with WebXR: ${error}`); + onfailed(c_str); + GodotRuntime.free(c_str); + }); + }).catch(function (error) { + const c_str = GodotRuntime.allocString(`Unable to start session: ${error}`); + onfailed(c_str); + GodotRuntime.free(c_str); + }); + }, + + godot_webxr_uninitialize__proxy: 'sync', + godot_webxr_uninitialize__sig: 'v', + godot_webxr_uninitialize: function () { + if (GodotWebXR.session) { + GodotWebXR.session.end() + // Prevent exception when session has already ended. + .catch((e) => { }); + } + + // Clean-up the textures we allocated for each view. + const gl = GodotWebXR.gl; + for (let i = 0; i < GodotWebXR.textures.length; i++) { + const texture = GodotWebXR.textures[i]; + if (texture !== null) { + 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; + } + + GodotWebXR.session = null; + GodotWebXR.space = null; + GodotWebXR.frame = null; + GodotWebXR.pose = null; + + // Disable the monkey-patched window.requestAnimationFrame() and + // pause/restart the main loop to activate it on all platforms. + GodotWebXR.monkeyPatchRequestAnimationFrame(false); + 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 () { + if (!GodotWebXR.session || !GodotWebXR.pose) { + return 0; + } + + const glLayer = GodotWebXR.session.renderState.baseLayer; + const view = GodotWebXR.pose.views[0]; + const viewport = glLayer.getViewport(view); + + const buf = GodotRuntime.malloc(2 * 4); + GodotRuntime.setHeapValue(buf + 0, viewport.width, 'i32'); + GodotRuntime.setHeapValue(buf + 4, viewport.height, 'i32'); + return buf; + }, + + godot_webxr_get_transform_for_eye__proxy: 'sync', + godot_webxr_get_transform_for_eye__sig: 'ii', + godot_webxr_get_transform_for_eye: function (p_eye) { + if (!GodotWebXR.session || !GodotWebXR.pose) { + return 0; + } + + const views = GodotWebXR.pose.views; + let matrix; + if (p_eye === 0) { + matrix = GodotWebXR.pose.transform.matrix; + } else { + matrix = views[p_eye - 1].transform.matrix; + } + const buf = GodotRuntime.malloc(16 * 4); + for (let i = 0; i < 16; i++) { + GodotRuntime.setHeapValue(buf + (i * 4), matrix[i], 'float'); + } + return buf; + }, + + godot_webxr_get_projection_for_eye__proxy: 'sync', + godot_webxr_get_projection_for_eye__sig: 'ii', + godot_webxr_get_projection_for_eye: function (p_eye) { + if (!GodotWebXR.session || !GodotWebXR.pose) { + return 0; + } + + const view_index = (p_eye === 2 /* ARVRInterface::EYE_RIGHT */) ? 1 : 0; + const matrix = GodotWebXR.pose.views[view_index].projectionMatrix; + const buf = GodotRuntime.malloc(16 * 4); + for (let i = 0; i < 16; i++) { + GodotRuntime.setHeapValue(buf + (i * 4), matrix[i], 'float'); + } + return buf; + }, + + 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) { + return 0; + } + + const view_index = (p_eye === 2 /* ARVRInterface::EYE_RIGHT */) ? 1 : 0; + if (GodotWebXR.texture_ids[view_index]) { + 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); + const gl = GodotWebXR.gl; + + const texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, viewport.width, viewport.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.bindTexture(gl.TEXTURE_2D, null); + + const texture_id = GL.getNewId(GL.textures); + GL.textures[texture_id] = texture; + GodotWebXR.textures[view_index] = texture; + GodotWebXR.texture_ids[view_index] = texture_id; + return texture_id; + }, + + godot_webxr_commit_for_eye__proxy: 'sync', + godot_webxr_commit_for_eye__sig: 'vi', + godot_webxr_commit_for_eye: function (p_eye) { + if (!GodotWebXR.session || !GodotWebXR.pose) { + return; + } + + const view_index = (p_eye === 2 /* ARVRInterface::EYE_RIGHT */) ? 1 : 0; + const glLayer = GodotWebXR.session.renderState.baseLayer; + const view = GodotWebXR.pose.views[view_index]; + const viewport = glLayer.getViewport(view); + const gl = GodotWebXR.gl; + + const orig_framebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING); + const orig_viewport = gl.getParameter(gl.VIEWPORT); + + // Bind to WebXR's framebuffer. + gl.bindFramebuffer(gl.FRAMEBUFFER, glLayer.framebuffer); + gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height); + + GodotWebXR.blitTexture(gl, GodotWebXR.textures[view_index]); + + // Restore state. + gl.bindFramebuffer(gl.FRAMEBUFFER, orig_framebuffer); + gl.viewport(orig_viewport[0], orig_viewport[1], orig_viewport[2], orig_viewport[3]); + }, + + godot_webxr_sample_controller_data__proxy: 'sync', + godot_webxr_sample_controller_data__sig: 'v', + godot_webxr_sample_controller_data: function () { + GodotWebXR.sampleControllers(); + }, + + godot_webxr_get_controller_count__proxy: 'sync', + godot_webxr_get_controller_count__sig: 'i', + godot_webxr_get_controller_count: function () { + if (!GodotWebXR.session || !GodotWebXR.frame) { + return 0; + } + return GodotWebXR.controllers.length; + }, + + godot_webxr_is_controller_connected__proxy: 'sync', + godot_webxr_is_controller_connected__sig: 'ii', + godot_webxr_is_controller_connected: function (p_controller) { + if (!GodotWebXR.session || !GodotWebXR.frame) { + return false; + } + return !!GodotWebXR.controllers[p_controller]; + }, + + godot_webxr_get_controller_transform__proxy: 'sync', + godot_webxr_get_controller_transform__sig: 'ii', + godot_webxr_get_controller_transform: function (p_controller) { + if (!GodotWebXR.session || !GodotWebXR.frame) { + return 0; + } + + const controller = GodotWebXR.controllers[p_controller]; + if (!controller) { + return 0; + } + + const frame = GodotWebXR.frame; + const space = GodotWebXR.space; + + const pose = frame.getPose(controller.targetRaySpace, space); + if (!pose) { + // This can mean that the controller lost tracking. + return 0; + } + const matrix = pose.transform.matrix; + + const buf = GodotRuntime.malloc(16 * 4); + for (let i = 0; i < 16; i++) { + GodotRuntime.setHeapValue(buf + (i * 4), matrix[i], 'float'); + } + return buf; + }, + + godot_webxr_get_controller_buttons__proxy: 'sync', + godot_webxr_get_controller_buttons__sig: 'ii', + godot_webxr_get_controller_buttons: function (p_controller) { + if (GodotWebXR.controllers.length === 0) { + return 0; + } + + const controller = GodotWebXR.controllers[p_controller]; + if (!controller || !controller.gamepad) { + return 0; + } + + const button_count = controller.gamepad.buttons.length; + + const buf = GodotRuntime.malloc((button_count + 1) * 4); + GodotRuntime.setHeapValue(buf, button_count, 'i32'); + for (let i = 0; i < button_count; i++) { + GodotRuntime.setHeapValue(buf + 4 + (i * 4), controller.gamepad.buttons[i].value, 'float'); + } + return buf; + }, + + godot_webxr_get_controller_axes__proxy: 'sync', + godot_webxr_get_controller_axes__sig: 'ii', + godot_webxr_get_controller_axes: function (p_controller) { + if (GodotWebXR.controllers.length === 0) { + return 0; + } + + const controller = GodotWebXR.controllers[p_controller]; + if (!controller || !controller.gamepad) { + return 0; + } + + const axes_count = controller.gamepad.axes.length; + + const buf = GodotRuntime.malloc((axes_count + 1) * 4); + GodotRuntime.setHeapValue(buf, axes_count, 'i32'); + for (let i = 0; i < axes_count; i++) { + 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; + }, + + godot_webxr_get_visibility_state__proxy: 'sync', + godot_webxr_get_visibility_state__sig: 'i', + godot_webxr_get_visibility_state: function () { + if (!GodotWebXR.session || !GodotWebXR.session.visibilityState) { + return 0; + } + + return GodotRuntime.allocString(GodotWebXR.session.visibilityState); + }, + + godot_webxr_get_bounds_geometry__proxy: 'sync', + godot_webxr_get_bounds_geometry__sig: 'i', + godot_webxr_get_bounds_geometry: function () { + if (!GodotWebXR.space || !GodotWebXR.space.boundsGeometry) { + return 0; + } + + const point_count = GodotWebXR.space.boundsGeometry.length; + if (point_count === 0) { + return 0; + } + + const buf = GodotRuntime.malloc(((point_count * 3) + 1) * 4); + GodotRuntime.setHeapValue(buf, point_count, 'i32'); + for (let i = 0; i < point_count; i++) { + const point = GodotWebXR.space.boundsGeometry[i]; + GodotRuntime.setHeapValue(buf + ((i * 3) + 1) * 4, point.x, 'float'); + GodotRuntime.setHeapValue(buf + ((i * 3) + 2) * 4, point.y, 'float'); + GodotRuntime.setHeapValue(buf + ((i * 3) + 3) * 4, point.z, 'float'); + } + + return buf; + }, +}; + +autoAddDeps(GodotWebXR, '$GodotWebXR'); +mergeInto(LibraryManager.library, GodotWebXR); diff --git a/modules/webxr/native/webxr.externs.js b/modules/webxr/native/webxr.externs.js new file mode 100644 index 0000000000..03dc05bc83 --- /dev/null +++ b/modules/webxr/native/webxr.externs.js @@ -0,0 +1,499 @@ +/** + * @type {XR} + */ +Navigator.prototype.xr; + +/** + * @constructor + */ +function XRSessionInit() {}; + +/** + * @type {Array<string>} + */ +XRSessionInit.prototype.requiredFeatures; + +/** + * @type {Array<string>} + */ +XRSessionInit.prototype.optionalFeatures; + +/** + * @constructor + */ +function XR() {} + +/** + * @type {?function (Event)} + */ +XR.prototype.ondevicechanged; + +/** + * @param {string} mode + * + * @return {!Promise<boolean>} + */ +XR.prototype.isSessionSupported = function(mode) {} + +/** + * @param {string} mode + * @param {XRSessionInit} options + * + * @return {!Promise<XRSession>} + */ +XR.prototype.requestSession = function(mode, options) {} + +/** + * @constructor + */ +function XRSession() {} + +/** + * @type {XRRenderState} + */ +XRSession.prototype.renderState; + +/** + * @type {Array<XRInputSource>} + */ +XRSession.prototype.inputSources; + +/** + * @type {string} + */ +XRSession.prototype.visibilityState; + +/** + * @type {?function (Event)} + */ +XRSession.prototype.onend; + +/** + * @type {?function (XRInputSourcesChangeEvent)} + */ +XRSession.prototype.oninputsourceschange; + +/** + * @type {?function (XRInputSourceEvent)} + */ +XRSession.prototype.onselectstart; + +/** + * @type {?function (XRInputSourceEvent)} + */ +XRSession.prototype.onselect; + +/** + * @type {?function (XRInputSourceEvent)} + */ +XRSession.prototype.onselectend; + +/** + * @type {?function (XRInputSourceEvent)} + */ +XRSession.prototype.onsqueezestart; + +/** + * @type {?function (XRInputSourceEvent)} + */ +XRSession.prototype.onsqueeze; + +/** + * @type {?function (XRInputSourceEvent)} + */ +XRSession.prototype.onsqueezeend; + +/** + * @type {?function (Event)} + */ +XRSession.prototype.onvisibilitychange; + +/** + * @param {XRRenderStateInit} state + * @return {void} + */ +XRSession.prototype.updateRenderState = function (state) {}; + +/** + * @param {XRFrameRequestCallback} callback + * @return {number} + */ +XRSession.prototype.requestAnimationFrame = function (callback) {}; + +/** + * @param {number} handle + * @return {void} + */ +XRSession.prototype.cancelAnimationFrame = function (handle) {}; + +/** + * @return {Promise<void>} + */ +XRSession.prototype.end = function () {}; + +/** + * @param {string} referenceSpaceType + * @return {Promise<XRReferenceSpace>} + */ +XRSession.prototype.requestReferenceSpace = function (referenceSpaceType) {}; + +/** + * @typedef {function(number, XRFrame): undefined} + */ +var XRFrameRequestCallback; + +/** + * @constructor + */ +function XRRenderStateInit() {} + +/** + * @type {number} + */ +XRRenderStateInit.prototype.depthNear; + +/** + * @type {number} + */ +XRRenderStateInit.prototype.depthFar; + +/** + * @type {number} + */ +XRRenderStateInit.prototype.inlineVerticalFieldOfView; + +/** + * @type {?XRWebGLLayer} + */ +XRRenderStateInit.prototype.baseLayer; + +/** + * @constructor + */ +function XRRenderState() {}; + +/** + * @type {number} + */ +XRRenderState.prototype.depthNear; + +/** + * @type {number} + */ +XRRenderState.prototype.depthFar; + +/** + * @type {?number} + */ +XRRenderState.prototype.inlineVerticalFieldOfView; + +/** + * @type {?XRWebGLLayer} + */ +XRRenderState.prototype.baseLayer; + +/** + * @constructor + */ +function XRFrame() {} + +/** + * @type {XRSession} + */ +XRFrame.prototype.session; + +/** + * @param {XRReferenceSpace} referenceSpace + * @return {?XRViewerPose} + */ +XRFrame.prototype.getViewerPose = function (referenceSpace) {}; + +/** + * + * @param {XRSpace} space + * @param {XRSpace} baseSpace + * @return {XRPose} + */ +XRFrame.prototype.getPose = function (space, baseSpace) {}; + +/** + * @constructor + */ +function XRReferenceSpace() {}; + +/** + * @type {Array<DOMPointReadOnly>} + */ +XRReferenceSpace.prototype.boundsGeometry; + +/** + * @param {XRRigidTransform} originOffset + * @return {XRReferenceSpace} + */ +XRReferenceSpace.prototype.getOffsetReferenceSpace = function(originOffset) {}; + +/** + * @type {?function (Event)} + */ +XRReferenceSpace.prototype.onreset; + +/** + * @constructor + */ +function XRRigidTransform() {}; + +/** + * @type {DOMPointReadOnly} + */ +XRRigidTransform.prototype.position; + +/** + * @type {DOMPointReadOnly} + */ +XRRigidTransform.prototype.orientation; + +/** + * @type {Float32Array} + */ +XRRigidTransform.prototype.matrix; + +/** + * @type {XRRigidTransform} + */ +XRRigidTransform.prototype.inverse; + +/** + * @constructor + */ +function XRView() {} + +/** + * @type {string} + */ +XRView.prototype.eye; + +/** + * @type {Float32Array} + */ +XRView.prototype.projectionMatrix; + +/** + * @type {XRRigidTransform} + */ +XRView.prototype.transform; + +/** + * @constructor + */ +function XRViewerPose() {} + +/** + * @type {Array<XRView>} + */ +XRViewerPose.prototype.views; + +/** + * @constructor + */ +function XRViewport() {} + +/** + * @type {number} + */ +XRViewport.prototype.x; + +/** + * @type {number} + */ +XRViewport.prototype.y; + +/** + * @type {number} + */ +XRViewport.prototype.width; + +/** + * @type {number} + */ +XRViewport.prototype.height; + +/** + * @constructor + */ +function XRWebGLLayerInit() {}; + +/** + * @type {boolean} + */ +XRWebGLLayerInit.prototype.antialias; + +/** + * @type {boolean} + */ +XRWebGLLayerInit.prototype.depth; + +/** + * @type {boolean} + */ +XRWebGLLayerInit.prototype.stencil; + +/** + * @type {boolean} + */ +XRWebGLLayerInit.prototype.alpha; + +/** + * @type {boolean} + */ +XRWebGLLayerInit.prototype.ignoreDepthValues; + +/** + * @type {boolean} + */ +XRWebGLLayerInit.prototype.ignoreDepthValues; + +/** + * @type {number} + */ +XRWebGLLayerInit.prototype.framebufferScaleFactor; + +/** + * @constructor + * + * @param {XRSession} session + * @param {WebGLRenderContext|WebGL2RenderingContext} ctx + * @param {?XRWebGLLayerInit} options + */ +function XRWebGLLayer(session, ctx, options) {} + +/** + * @type {boolean} + */ +XRWebGLLayer.prototype.antialias; + +/** + * @type {boolean} + */ +XRWebGLLayer.prototype.ignoreDepthValues; + +/** + * @type {number} + */ +XRWebGLLayer.prototype.framebufferWidth; + +/** + * @type {number} + */ +XRWebGLLayer.prototype.framebufferHeight; + +/** + * @type {WebGLFramebuffer} + */ +XRWebGLLayer.prototype.framebuffer; + +/** + * @param {XRView} view + * @return {?XRViewport} + */ +XRWebGLLayer.prototype.getViewport = function(view) {}; + +/** + * @param {XRSession} session + * @return {number} + */ +XRWebGLLayer.prototype.getNativeFramebufferScaleFactor = function (session) {}; + +/** + * @constructor + */ +function WebGLRenderingContextBase() {}; + +/** + * @return {Promise<void>} + */ +WebGLRenderingContextBase.prototype.makeXRCompatible = function () {}; + +/** + * @constructor + */ +function XRInputSourcesChangeEvent() {}; + +/** + * @type {Array<XRInputSource>} + */ +XRInputSourcesChangeEvent.prototype.added; + +/** + * @type {Array<XRInputSource>} + */ +XRInputSourcesChangeEvent.prototype.removed; + +/** + * @constructor + */ +function XRInputSourceEvent() {}; + +/** + * @type {XRFrame} + */ +XRInputSourceEvent.prototype.frame; + +/** + * @type {XRInputSource} + */ +XRInputSourceEvent.prototype.inputSource; + +/** + * @constructor + */ +function XRInputSource() {}; + +/** + * @type {Gamepad} + */ +XRInputSource.prototype.gamepad; + +/** + * @type {XRSpace} + */ +XRInputSource.prototype.gripSpace; + +/** + * @type {string} + */ +XRInputSource.prototype.handedness; + +/** + * @type {string} + */ +XRInputSource.prototype.profiles; + +/** + * @type {string} + */ +XRInputSource.prototype.targetRayMode; + +/** + * @type {XRSpace} + */ +XRInputSource.prototype.targetRaySpace; + +/** + * @constructor + */ +function XRSpace() {}; + +/** + * @constructor + */ +function XRPose() {}; + +/** + * @type {XRRigidTransform} + */ +XRPose.prototype.transform; + +/** + * @type {boolean} + */ +XRPose.prototype.emulatedPosition; diff --git a/modules/icloud/icloud_module.cpp b/modules/webxr/register_types.cpp index 8a2c41a38c..8baf7e05b8 100644 --- a/modules/icloud/icloud_module.cpp +++ b/modules/webxr/register_types.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* icloud_module.cpp */ +/* register_types.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,21 +28,20 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "icloud_module.h" +#include "register_types.h" -#include "core/config/engine.h" +#include "webxr_interface.h" +#include "webxr_interface_js.h" -#include "icloud.h" +void register_webxr_types() { + ClassDB::register_virtual_class<WebXRInterface>(); -ICloud *icloud; - -void register_icloud_types() { - icloud = memnew(ICloud); - Engine::get_singleton()->add_singleton(Engine::Singleton("ICloud", icloud)); +#ifdef JAVASCRIPT_ENABLED + Ref<WebXRInterfaceJS> webxr; + webxr.instance(); + XRServer::get_singleton()->add_interface(webxr); +#endif } -void unregister_icloud_types() { - if (icloud) { - memdelete(icloud); - } +void unregister_webxr_types() { } diff --git a/modules/gamecenter/game_center_delegate.h b/modules/webxr/register_types.h index ef1d2ae93d..f0c5a4bd79 100644 --- a/modules/gamecenter/game_center_delegate.h +++ b/modules/webxr/register_types.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* game_center_delegate.h */ +/* register_types.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#import <GameKit/GameKit.h> +#ifndef WEBXR_REGISTER_TYPES_H +#define WEBXR_REGISTER_TYPES_H -@interface GodotGameCenterDelegate : NSObject <GKGameCenterControllerDelegate> +void register_webxr_types(); +void unregister_webxr_types(); -@end +#endif // WEBXR_REGISTER_TYPES_H diff --git a/modules/webxr/webxr_interface.cpp b/modules/webxr/webxr_interface.cpp new file mode 100644 index 0000000000..3e8e75bf0e --- /dev/null +++ b/modules/webxr/webxr_interface.cpp @@ -0,0 +1,71 @@ +/*************************************************************************/ +/* webxr_interface.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 "webxr_interface.h" +#include <stdlib.h> + +void WebXRInterface::_bind_methods() { + ClassDB::bind_method(D_METHOD("is_session_supported", "session_mode"), &WebXRInterface::is_session_supported); + ClassDB::bind_method(D_METHOD("set_session_mode", "session_mode"), &WebXRInterface::set_session_mode); + ClassDB::bind_method(D_METHOD("get_session_mode"), &WebXRInterface::get_session_mode); + ClassDB::bind_method(D_METHOD("set_required_features", "required_features"), &WebXRInterface::set_required_features); + ClassDB::bind_method(D_METHOD("get_required_features"), &WebXRInterface::get_required_features); + ClassDB::bind_method(D_METHOD("set_optional_features", "optional_features"), &WebXRInterface::set_optional_features); + ClassDB::bind_method(D_METHOD("get_optional_features"), &WebXRInterface::get_optional_features); + ClassDB::bind_method(D_METHOD("get_reference_space_type"), &WebXRInterface::get_reference_space_type); + ClassDB::bind_method(D_METHOD("set_requested_reference_space_types", "requested_reference_space_types"), &WebXRInterface::set_requested_reference_space_types); + ClassDB::bind_method(D_METHOD("get_requested_reference_space_types"), &WebXRInterface::get_requested_reference_space_types); + ClassDB::bind_method(D_METHOD("get_controller", "controller_id"), &WebXRInterface::get_controller); + ClassDB::bind_method(D_METHOD("get_visibility_state"), &WebXRInterface::get_visibility_state); + ClassDB::bind_method(D_METHOD("get_bounds_geometry"), &WebXRInterface::get_bounds_geometry); + + ADD_PROPERTY(PropertyInfo(Variant::STRING, "session_mode", PROPERTY_HINT_NONE), "set_session_mode", "get_session_mode"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "required_features", PROPERTY_HINT_NONE), "set_required_features", "get_required_features"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "optional_features", PROPERTY_HINT_NONE), "set_optional_features", "get_optional_features"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "requested_reference_space_types", PROPERTY_HINT_NONE), "set_requested_reference_space_types", "get_requested_reference_space_types"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "reference_space_type", PROPERTY_HINT_NONE), "", "get_reference_space_type"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "visibility_state", PROPERTY_HINT_NONE), "", "get_visibility_state"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_ARRAY, "bounds_geometry", PROPERTY_HINT_NONE), "", "get_bounds_geometry"); + + ADD_SIGNAL(MethodInfo("session_supported", PropertyInfo(Variant::STRING, "session_mode"), PropertyInfo(Variant::BOOL, "supported"))); + ADD_SIGNAL(MethodInfo("session_started")); + ADD_SIGNAL(MethodInfo("session_ended")); + ADD_SIGNAL(MethodInfo("session_failed", PropertyInfo(Variant::STRING, "message"))); + + ADD_SIGNAL(MethodInfo("selectstart", PropertyInfo(Variant::INT, "controller_id"))); + ADD_SIGNAL(MethodInfo("select", PropertyInfo(Variant::INT, "controller_id"))); + ADD_SIGNAL(MethodInfo("selectend", PropertyInfo(Variant::INT, "controller_id"))); + ADD_SIGNAL(MethodInfo("squeezestart", PropertyInfo(Variant::INT, "controller_id"))); + ADD_SIGNAL(MethodInfo("squeeze", PropertyInfo(Variant::INT, "controller_id"))); + ADD_SIGNAL(MethodInfo("squeezeend", PropertyInfo(Variant::INT, "controller_id"))); + + ADD_SIGNAL(MethodInfo("visibility_state_changed")); + ADD_SIGNAL(MethodInfo("reference_space_reset")); +} diff --git a/modules/gamecenter/game_center.h b/modules/webxr/webxr_interface.h index 1ac00ca126..c5b2dc8d73 100644 --- a/modules/gamecenter/game_center.h +++ b/modules/webxr/webxr_interface.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* game_center.h */ +/* webxr_interface.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,44 +28,38 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GAME_CENTER_H -#define GAME_CENTER_H +#ifndef WEBXR_INTERFACE_H +#define WEBXR_INTERFACE_H -#include "core/object/class_db.h" +#include "servers/xr/xr_interface.h" +#include "servers/xr/xr_positional_tracker.h" -class GameCenter : public Object { - GDCLASS(GameCenter, Object); +/** + @author David Snopek <david.snopek@snopekgames.com> - static GameCenter *instance; - static void _bind_methods(); - - List<Variant> pending_events; + The WebXR interface is a VR/AR interface that can be used on the web. +*/ - bool authenticated; +class WebXRInterface : public XRInterface { + GDCLASS(WebXRInterface, XRInterface); - void return_connect_error(const char *p_error_description); +protected: + static void _bind_methods(); 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(); - - void game_center_closed(); - - int get_pending_event_count(); - Variant pop_pending_event(); - - static GameCenter *get_singleton(); - - GameCenter(); - ~GameCenter(); + virtual void is_session_supported(const String &p_session_mode) = 0; + virtual void set_session_mode(String p_session_mode) = 0; + virtual String get_session_mode() const = 0; + virtual void set_required_features(String p_required_features) = 0; + virtual String get_required_features() const = 0; + virtual void set_optional_features(String p_optional_features) = 0; + virtual String get_optional_features() const = 0; + virtual void set_requested_reference_space_types(String p_requested_reference_space_types) = 0; + virtual String get_requested_reference_space_types() const = 0; + virtual String get_reference_space_type() const = 0; + virtual XRPositionalTracker *get_controller(int p_controller_id) const = 0; + virtual String get_visibility_state() const = 0; + virtual PackedVector3Array get_bounds_geometry() const = 0; }; -#endif +#endif // WEBXR_INTERFACE_H diff --git a/modules/webxr/webxr_interface_js.cpp b/modules/webxr/webxr_interface_js.cpp new file mode 100644 index 0000000000..74789fc98e --- /dev/null +++ b/modules/webxr/webxr_interface_js.cpp @@ -0,0 +1,460 @@ +/*************************************************************************/ +/* webxr_interface_js.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. */ +/*************************************************************************/ + +#ifdef JAVASCRIPT_ENABLED + +#include "webxr_interface_js.h" +#include "core/input/input.h" +#include "core/os/os.h" +#include "emscripten.h" +#include "godot_webxr.h" +#include <stdlib.h> + +void _emwebxr_on_session_supported(char *p_session_mode, int p_supported) { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); + + Ref<XRInterface> interface = xr_server->find_interface("WebXR"); + ERR_FAIL_COND(interface.is_null()); + + String session_mode = String(p_session_mode); + interface->emit_signal("session_supported", session_mode, p_supported ? true : false); +} + +void _emwebxr_on_session_started(char *p_reference_space_type) { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); + + Ref<XRInterface> interface = xr_server->find_interface("WebXR"); + ERR_FAIL_COND(interface.is_null()); + + String reference_space_type = String(p_reference_space_type); + ((WebXRInterfaceJS *)interface.ptr())->_set_reference_space_type(reference_space_type); + interface->emit_signal("session_started"); +} + +void _emwebxr_on_session_ended() { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); + + Ref<XRInterface> interface = xr_server->find_interface("WebXR"); + ERR_FAIL_COND(interface.is_null()); + + interface->uninitialize(); + interface->emit_signal("session_ended"); +} + +void _emwebxr_on_session_failed(char *p_message) { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); + + 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); +} + +void _emwebxr_on_controller_changed() { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); + + Ref<XRInterface> interface = xr_server->find_interface("WebXR"); + ERR_FAIL_COND(interface.is_null()); + + ((WebXRInterfaceJS *)interface.ptr())->_on_controller_changed(); +} + +extern "C" EMSCRIPTEN_KEEPALIVE void _emwebxr_on_input_event(char *p_signal_name, int p_input_source) { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); + + Ref<XRInterface> interface = xr_server->find_interface("WebXR"); + ERR_FAIL_COND(interface.is_null()); + + StringName signal_name = StringName(p_signal_name); + interface->emit_signal(signal_name, p_input_source + 1); +} + +extern "C" EMSCRIPTEN_KEEPALIVE void _emwebxr_on_simple_event(char *p_signal_name) { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); + + Ref<XRInterface> interface = xr_server->find_interface("WebXR"); + ERR_FAIL_COND(interface.is_null()); + + StringName signal_name = StringName(p_signal_name); + interface->emit_signal(signal_name); +} + +void WebXRInterfaceJS::is_session_supported(const String &p_session_mode) { + godot_webxr_is_session_supported(p_session_mode.utf8().get_data(), &_emwebxr_on_session_supported); +} + +void WebXRInterfaceJS::set_session_mode(String p_session_mode) { + session_mode = p_session_mode; +} + +String WebXRInterfaceJS::get_session_mode() const { + return session_mode; +} + +void WebXRInterfaceJS::set_required_features(String p_required_features) { + required_features = p_required_features; +} + +String WebXRInterfaceJS::get_required_features() const { + return required_features; +} + +void WebXRInterfaceJS::set_optional_features(String p_optional_features) { + optional_features = p_optional_features; +} + +String WebXRInterfaceJS::get_optional_features() const { + return optional_features; +} + +void WebXRInterfaceJS::set_requested_reference_space_types(String p_requested_reference_space_types) { + requested_reference_space_types = p_requested_reference_space_types; +} + +String WebXRInterfaceJS::get_requested_reference_space_types() const { + return requested_reference_space_types; +} + +void WebXRInterfaceJS::_set_reference_space_type(String p_reference_space_type) { + reference_space_type = p_reference_space_type; +} + +String WebXRInterfaceJS::get_reference_space_type() const { + return reference_space_type; +} + +XRPositionalTracker *WebXRInterfaceJS::get_controller(int p_controller_id) const { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, nullptr); + + return xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id); +} + +String WebXRInterfaceJS::get_visibility_state() const { + char *c_str = godot_webxr_get_visibility_state(); + if (c_str) { + String visibility_state = String(c_str); + free(c_str); + + return visibility_state; + } + return String(); +} + +PackedVector3Array WebXRInterfaceJS::get_bounds_geometry() const { + PackedVector3Array ret; + + int *js_bounds = godot_webxr_get_bounds_geometry(); + if (js_bounds) { + ret.resize(js_bounds[0]); + for (int i = 0; i < js_bounds[0]; i++) { + float *js_vector3 = ((float *)js_bounds) + (i * 3) + 1; + ret.set(i, Vector3(js_vector3[0], js_vector3[1], js_vector3[2])); + } + free(js_bounds); + } + + return ret; +} + +StringName WebXRInterfaceJS::get_name() const { + return "WebXR"; +}; + +int WebXRInterfaceJS::get_capabilities() const { + return XRInterface::XR_STEREO | XRInterface::XR_MONO; +}; + +bool WebXRInterfaceJS::is_stereo() { + return godot_webxr_get_view_count() == 2; +}; + +bool WebXRInterfaceJS::is_initialized() const { + return (initialized); +}; + +bool WebXRInterfaceJS::initialize() { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, false); + + if (!initialized) { + if (!godot_webxr_is_supported()) { + return false; + } + + if (requested_reference_space_types.size() == 0) { + return false; + } + + // 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( + session_mode.utf8().get_data(), + required_features.utf8().get_data(), + optional_features.utf8().get_data(), + requested_reference_space_types.utf8().get_data(), + &_emwebxr_on_session_started, + &_emwebxr_on_session_ended, + &_emwebxr_on_session_failed, + &_emwebxr_on_controller_changed, + &_emwebxr_on_input_event, + &_emwebxr_on_simple_event); + }; + + return true; +}; + +void WebXRInterfaceJS::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); + } + + godot_webxr_uninitialize(); + + reference_space_type = ""; + initialized = false; + }; +}; + +Transform WebXRInterfaceJS::_js_matrix_to_transform(float *p_js_matrix) { + Transform transform; + + transform.basis.elements[0].x = p_js_matrix[0]; + transform.basis.elements[1].x = p_js_matrix[1]; + transform.basis.elements[2].x = p_js_matrix[2]; + transform.basis.elements[0].y = p_js_matrix[4]; + transform.basis.elements[1].y = p_js_matrix[5]; + transform.basis.elements[2].y = p_js_matrix[6]; + transform.basis.elements[0].z = p_js_matrix[8]; + transform.basis.elements[1].z = p_js_matrix[9]; + transform.basis.elements[2].z = p_js_matrix[10]; + transform.origin.x = p_js_matrix[12]; + transform.origin.y = p_js_matrix[13]; + transform.origin.z = p_js_matrix[14]; + + return transform; +} + +Size2 WebXRInterfaceJS::get_render_targetsize() { + 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 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; + } + + render_targetsize.width = js_size[0]; + render_targetsize.height = js_size[1]; + + free(js_size); + + return render_targetsize; +}; + +Transform WebXRInterfaceJS::get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform) { + Transform transform_for_eye; + + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, transform_for_eye); + + float *js_matrix = godot_webxr_get_transform_for_eye(p_eye); + if (!initialized || js_matrix == nullptr) { + transform_for_eye = p_cam_transform; + return transform_for_eye; + } + + transform_for_eye = _js_matrix_to_transform(js_matrix); + free(js_matrix); + + return p_cam_transform * xr_server->get_reference_frame() * transform_for_eye; +}; + +CameraMatrix WebXRInterfaceJS::get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) { + CameraMatrix eye; + + float *js_matrix = godot_webxr_get_projection_for_eye(p_eye); + if (!initialized || js_matrix == nullptr) { + return eye; + } + + int k = 0; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + eye.matrix[i][j] = js_matrix[k++]; + } + } + + free(js_matrix); + + // Copied from godot_oculus_mobile's ovr_mobile_session.cpp + eye.matrix[2][2] = -(p_z_far + p_z_near) / (p_z_far - p_z_near); + eye.matrix[3][2] = -(2.0f * p_z_far * p_z_near) / (p_z_far - p_z_near); + + return eye; +} + +unsigned int WebXRInterfaceJS::get_external_texture_for_eye(XRInterface::Eyes p_eye) { + if (!initialized) { + return 0; + } + return godot_webxr_get_external_texture_for_eye(p_eye); +} + +void WebXRInterfaceJS::commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) { + if (!initialized) { + return; + } + godot_webxr_commit_for_eye(p_eye); +}; + +void WebXRInterfaceJS::process() { + if (initialized) { + godot_webxr_sample_controller_data(); + + int controller_count = godot_webxr_get_controller_count(); + if (controller_count == 0) { + return; + } + + for (int i = 0; i < controller_count; i++) { + _update_tracker(i); + } + }; +}; + +void WebXRInterfaceJS::_update_tracker(int p_controller_id) { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); + + XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id + 1); + if (godot_webxr_is_controller_connected(p_controller_id)) { + if (tracker == nullptr) { + tracker = memnew(XRPositionalTracker); + 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_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); + xr_server->add_tracker(tracker); + } + + Input *input = Input::get_singleton(); + + float *tracker_matrix = godot_webxr_get_controller_transform(p_controller_id); + if (tracker_matrix) { + Transform transform = _js_matrix_to_transform(tracker_matrix); + tracker->set_position(transform.origin); + tracker->set_orientation(transform.basis); + free(tracker_matrix); + } + + int *buttons = godot_webxr_get_controller_buttons(p_controller_id); + if (buttons) { + for (int i = 0; i < buttons[0]; i++) { + input->joy_button(p_controller_id + 100, i, *((float *)buttons + (i + 1))); + } + free(buttons); + } + + int *axes = godot_webxr_get_controller_axes(p_controller_id); + if (axes) { + for (int i = 0; i < axes[0]; i++) { + Input::JoyAxis joy_axis; + joy_axis.min = -1; + joy_axis.value = *((float *)axes + (i + 1)); + input->joy_axis(p_controller_id + 100, i, joy_axis); + } + free(axes); + } + } else if (tracker) { + xr_server->remove_tracker(tracker); + } +} + +void WebXRInterfaceJS::_on_controller_changed() { + // Register "virtual" gamepads with Godot for the ones we get from WebXR. + godot_webxr_sample_controller_data(); + for (int i = 0; i < 2; i++) { + bool controller_connected = godot_webxr_is_controller_connected(i); + if (controllers_state[i] != controller_connected) { + Input::get_singleton()->joy_connection_changed(i + 100, controller_connected, i == 0 ? "Left" : "Right", ""); + controllers_state[i] = controller_connected; + } + } +} + +void WebXRInterfaceJS::notification(int p_what) { + // Nothing to do here. +} + +WebXRInterfaceJS::WebXRInterfaceJS() { + initialized = false; + session_mode = "inline"; + requested_reference_space_types = "local"; +}; + +WebXRInterfaceJS::~WebXRInterfaceJS() { + // and make sure we cleanup if we haven't already + if (initialized) { + uninitialize(); + }; +}; + +#endif // JAVASCRIPT_ENABLED diff --git a/modules/arkit/arkit_interface.h b/modules/webxr/webxr_interface_js.h index f9b7709aba..49299b252f 100644 --- a/modules/arkit/arkit_interface.h +++ b/modules/webxr/webxr_interface_js.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* arkit_interface.h */ +/* webxr_interface_js.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,85 +28,52 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef ARKIT_INTERFACE_H -#define ARKIT_INTERFACE_H +#ifndef WEBXR_INTERFACE_JS_H +#define WEBXR_INTERFACE_JS_H -#include "servers/camera/camera_feed.h" -#include "servers/xr/xr_interface.h" -#include "servers/xr/xr_positional_tracker.h" +#ifdef JAVASCRIPT_ENABLED + +#include "webxr_interface.h" /** - @author Bastiaan Olij <mux213@gmail.com> + @author David Snopek <david.snopek@snopekgames.com> - ARKit interface between iPhone and Godot + The WebXR interface is a VR/AR interface that can be used on the web. */ -// 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); +class WebXRInterfaceJS : public WebXRInterface { + GDCLASS(WebXRInterfaceJS, WebXRInterface); 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(); + String session_mode; + String required_features; + String optional_features; + String requested_reference_space_types; + String reference_space_type; - 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 controllers_state[2]; + Size2 render_targetsize; - bool get_light_estimation_is_enabled() const; - void set_light_estimation_is_enabled(bool p_enable); + Transform _js_matrix_to_transform(float *p_js_matrix); + void _update_tracker(int p_controller_id); - 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; +public: + virtual void is_session_supported(const String &p_session_mode) override; + virtual void set_session_mode(String p_session_mode) override; + virtual String get_session_mode() const override; + virtual void set_required_features(String p_required_features) override; + virtual String get_required_features() const override; + virtual void set_optional_features(String p_optional_features) override; + virtual String get_optional_features() const override; + virtual void set_requested_reference_space_types(String p_requested_reference_space_types) override; + virtual String get_requested_reference_space_types() const override; + void _set_reference_space_type(String p_reference_space_type); + virtual String get_reference_space_type() const override; + virtual XRPositionalTracker *get_controller(int p_controller_id) const override; + virtual String get_visibility_state() const override; + virtual PackedVector3Array get_bounds_geometry() const override; virtual StringName get_name() const override; virtual int get_capabilities() const override; @@ -119,16 +86,18 @@ public: 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 unsigned int get_external_texture_for_eye(XRInterface::Eyes p_eye) override; virtual void commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) override; virtual void process() override; + virtual void notification(int p_what) 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); + void _on_controller_changed(); - ARKitInterface(); - ~ARKitInterface(); + WebXRInterfaceJS(); + ~WebXRInterfaceJS(); }; -#endif /* !ARKIT_INTERFACE_H */ +#endif // JAVASCRIPT_ENABLED + +#endif // WEBXR_INTERFACE_JS_H diff --git a/modules/xatlas_unwrap/register_types.cpp b/modules/xatlas_unwrap/register_types.cpp index 9f6e7efb27..880fe2df61 100644 --- a/modules/xatlas_unwrap/register_types.cpp +++ b/modules/xatlas_unwrap/register_types.cpp @@ -163,8 +163,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..ee28959adc 100644 --- a/platform/android/audio_driver_jandroid.cpp +++ b/platform/android/audio_driver_jandroid.cpp @@ -72,7 +72,7 @@ Error AudioDriverAndroid::init() { // __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device"); - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); int mix_rate = GLOBAL_GET("audio/mix_rate"); int latency = GLOBAL_GET("audio/output_latency"); @@ -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..0e696024a9 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_NDK_ROOT" in os.environ) or ("ANDROID_SDK_ROOT" in os.environ) or ("ANDROID_HOME" in os.environ) def get_platform(platform): @@ -24,13 +24,36 @@ 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. +# If the env variable is already defined, we use it with the expectation that +# the user knows what they're doing (e.g: testing a new NDK version). +# Otherwise, we generate one for this build using the ANDROID_SDK_ROOT env +# variable and the project ndk version. +def get_android_ndk_root(): + if "ANDROID_NDK_ROOT" in os.environ: + return os.environ.get("ANDROID_NDK_ROOT", 0) + else: + return get_android_sdk_root() + "/ndk/" + get_project_ndk_version() + + def get_flags(): return [ ("tools", False), @@ -47,7 +70,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 +317,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 +370,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.3.6528147" + + # 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..a963c5a741 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -261,7 +261,7 @@ 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; @@ -269,7 +269,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { Vector<Device> devices; volatile bool devices_changed; Mutex device_lock; - Thread *check_for_changes_thread; + Thread check_for_changes_thread; volatile bool quit_request; static void _check_for_changes_poll_thread(void *ud) { @@ -280,7 +280,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { { // Nothing to do if we already know the plugins have changed. if (!ea->plugins_changed) { - Vector<PluginConfig> loaded_plugins = get_plugins(); + Vector<PluginConfigAndroid> loaded_plugins = get_plugins(); MutexLock lock(ea->plugins_lock); @@ -308,7 +308,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 +361,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; @@ -432,7 +432,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 +629,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 +639,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 +653,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 +666,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); @@ -1618,7 +1618,7 @@ 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)); @@ -1800,7 +1800,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 +1815,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 +1832,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 +1843,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 +1857,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 +1885,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); @@ -2131,7 +2131,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; @@ -2288,7 +2288,7 @@ public: args.push_back(user); args.push_back(export_path); 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; @@ -2303,7 +2303,7 @@ public: args.push_back("--verbose"); args.push_back(export_path); - 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; @@ -2438,9 +2438,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); @@ -2848,13 +2848,12 @@ public: devices_changed = true; plugins_changed = true; quit_request = false; - check_for_changes_thread = Thread::create(_check_for_changes_poll_thread, this); + 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); + check_for_changes_thread.wait_to_finish(); } }; diff --git a/platform/android/java/app/build.gradle b/platform/android/java/app/build.gradle index 53d11fda5b..814cc30613 100644 --- a/platform/android/java/app/build.gradle +++ b/platform/android/java/app/build.gradle @@ -98,6 +98,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..8d3aa8a6b0 100644 --- a/platform/android/java/app/config.gradle +++ b/platform/android/java/app/config.gradle @@ -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.3.6528147' // Also update 'platform/android/detect.py#get_project_ndk_version()' when this is updated. ] diff --git a/platform/android/java/lib/build.gradle b/platform/android/java/lib/build.gradle index 89ce3d15e6..6260cadffb 100644 --- a/platform/android/java/lib/build.gradle +++ b/platform/android/java/lib/build.gradle @@ -68,7 +68,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/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/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..4ee4427aa0 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 { 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/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/export/export.cpp b/platform/iphone/export/export.cpp index 3253112bf3..91cecdd704 100644 --- a/platform/iphone/export/export.cpp +++ b/platform/iphone/export/export.cpp @@ -57,10 +57,10 @@ class EditorExportPlatformIOS : public EditorExportPlatform { // Plugins volatile bool plugins_changed; - Thread *check_for_changes_thread; + Thread check_for_changes_thread; volatile bool 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); @@ -146,7 +146,7 @@ class EditorExportPlatformIOS : public EditorExportPlatform { if (!ea->plugins_changed) { 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; @@ -241,7 +241,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 +251,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 +262,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 +275,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); @@ -360,7 +360,7 @@ 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)); } @@ -979,7 +979,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 +1229,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 +1345,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 +1419,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 +1506,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 +1600,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 +1688,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 +1696,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 +1873,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 +1888,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."); @@ -1945,13 +1970,12 @@ EditorExportPlatformIOS::EditorExportPlatformIOS() { plugins_changed = true; quit_request = false; - 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); + 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.libs.js b/platform/javascript/.eslintrc.libs.js index e5f0c3d147..81b1b8c864 100644 --- a/platform/javascript/.eslintrc.libs.js +++ b/platform/javascript/.eslintrc.libs.js @@ -18,5 +18,8 @@ module.exports = { "GodotRuntime": true, "GodotFS": true, "IDHandler": true, + "Browser": true, + "GL": true, + "XRWebGLLayer": true, }, }; diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub index 7a8005fe30..11a45d2811 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,6 +68,8 @@ else: build = sys_env.Program(build_targets, javascript_files + ["javascript_runtime.cpp"]) sys_env.Depends(build[0], sys_env["JS_LIBS"]) +sys_env.Depends(build[0], sys_env["JS_PRE"]) +sys_env.Depends(build[0], sys_env["JS_EXTERNS"]) engine = [ "js/engine/preloader.js", @@ -90,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..f7cc9e6540 100644 --- a/platform/javascript/audio_driver_javascript.cpp +++ b/platform/javascript/audio_driver_javascript.cpp @@ -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 d53c774e77..653d18f791 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 +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 @@ -131,8 +139,16 @@ 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") diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp index f10627b0b6..cfe093693f 100644 --- a/platform/javascript/display_server_javascript.cpp +++ b/platform/javascript/display_server_javascript.cpp @@ -93,7 +93,7 @@ EM_BOOL DisplayServerJavaScript::fullscreen_change_callback(int p_event_type, co 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 +455,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 +558,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"); @@ -766,9 +760,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 +774,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 +786,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); } @@ -1026,8 +1015,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..e28fbc56f3 100644 --- a/platform/javascript/display_server_javascript.h +++ b/platform/javascript/display_server_javascript.h @@ -86,7 +86,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(); diff --git a/platform/javascript/emscripten_helpers.py b/platform/javascript/emscripten_helpers.py index cc874c432e..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,6 +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): + env.Append(JS_PRE=env.File(js_pre)) + + +def add_js_externs(env, externs): + env.Append(JS_EXTERNS=env.File(externs)) diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp index 48ccc1f87a..f5d8a68994 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, @@ -681,7 +682,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 +703,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..0006848756 100644 --- a/platform/javascript/godot_js.h +++ b/platform/javascript/godot_js.h @@ -76,6 +76,12 @@ 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)); diff --git a/platform/javascript/http_client_javascript.cpp b/platform/javascript/http_client_javascript.cpp index 44819c495c..c8c48dd582 100644 --- a/platform/javascript/http_client_javascript.cpp +++ b/platform/javascript/http_client_javascript.cpp @@ -220,13 +220,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/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/engine.js b/platform/javascript/js/engine/engine.js index 4b8a7dde69..01232cbece 100644 --- a/platform/javascript/js/engine/engine.js +++ b/platform/javascript/js/engine/engine.js @@ -62,7 +62,7 @@ const Engine = (function () { // Emscripten configuration. config['thisProgram'] = me.executableName; config['noExitRuntime'] = true; - config['dynamicLibraries'] = me.gdnativeLibs; + config['dynamicLibraries'] = [`${me.executableName}.side.wasm`].concat(me.gdnativeLibs); Godot(config).then(function (module) { module['initFS'](me.persistentPaths).then(function (fs_err) { me.rtenv = module; diff --git a/platform/javascript/js/libs/library_godot_display.js b/platform/javascript/js/libs/library_godot_display.js index d1f4d9595b..2977b7c122 100644 --- a/platform/javascript/js/libs/library_godot_display.js +++ b/platform/javascript/js/libs/library_godot_display.js @@ -269,13 +269,140 @@ 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); + /** * 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'], $GodotDisplay: { window_icon: '', }, @@ -491,6 +618,49 @@ const GodotDisplay = { }, false); GodotDisplayListeners.add(canvas, 'drop', GodotDisplayDragDrop.handler(dropFiles)); }, + + /* + * 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/os_javascript.cpp b/platform/javascript/os_javascript.cpp index 3fb5d4ad6a..b922b2ba91 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; } diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h index 9c8da0c898..8db62d9d1c 100644 --- a/platform/javascript/os_javascript.h +++ b/platform/javascript/os_javascript.h @@ -70,7 +70,8 @@ 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; diff --git a/platform/linuxbsd/SCsub b/platform/linuxbsd/SCsub index 6e43ffcedb..ddc698a55b 100644 --- a/platform/linuxbsd/SCsub +++ b/platform/linuxbsd/SCsub @@ -18,5 +18,5 @@ common_x11 = [ 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..13d1fe3237 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": @@ -390,4 +390,7 @@ 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++"]) diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index 1ee5cd3923..53baf17858 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); } @@ -3360,7 +3360,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 +4266,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]); @@ -4280,9 +4280,7 @@ DisplayServerX11::~DisplayServerX11() { _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.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..906710f933 100644 --- a/platform/linuxbsd/display_server_x11.h +++ b/platform/linuxbsd/display_server_x11.h @@ -252,7 +252,7 @@ class DisplayServerX11 : public DisplayServer { void _dispatch_input_event(const Ref<InputEvent> &p_event); mutable Mutex events_mutex; - Thread *events_thread = nullptr; + Thread events_thread; bool events_thread_done = false; LocalVector<XEvent> polled_events; static void _poll_events_thread(void *ud); diff --git a/platform/linuxbsd/joypad_linux.cpp b/platform/linuxbsd/joypad_linux.cpp index 291ca49585..4e96e6d687 100644 --- a/platform/linuxbsd/joypad_linux.cpp +++ b/platform/linuxbsd/joypad_linux.cpp @@ -32,6 +32,7 @@ #include "joypad_linux.h" +#include <dirent.h> #include <errno.h> #include <fcntl.h> #include <linux/input.h> @@ -73,13 +74,12 @@ void JoypadLinux::Joypad::reset() { JoypadLinux::JoypadLinux(Input *in) { exit_udev = false; 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); + joy_thread.wait_to_finish(); close_joypad(); } @@ -183,13 +183,23 @@ void JoypadLinux::monitor_joypads() { { 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..bf343b7ceb 100644 --- a/platform/linuxbsd/joypad_linux.h +++ b/platform/linuxbsd/joypad_linux.h @@ -72,7 +72,7 @@ private: bool exit_udev; Mutex joy_mutex; - Thread *joy_thread; + Thread joy_thread; Input *input; Joypad joypads[JOYPADS_MAX]; Vector<String> attached_devices; 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.mm b/platform/osx/display_server_osx.mm index bb3c1d47b7..2d43454501 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; 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..1c3fa990fe 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": 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..8b60e55d2d 100644 --- a/platform/uwp/os_uwp.cpp +++ b/platform/uwp/os_uwp.cpp @@ -39,14 +39,12 @@ #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 +129,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 +633,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..97ecacd247 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), @@ -208,7 +208,7 @@ def configure_msvc(env, manual_msvc_config): env.AppendUnique(CPPDEFINES=["DEBUG_ENABLED"]) env.Append(LINKFLAGS=["/DEBUG"]) - if env["debug_symbols"] == "yes": + if env["debug_symbols"]: env.AppendUnique(CCFLAGS=["/Z7"]) env.AppendUnique(LINKFLAGS=["/DEBUG"]) @@ -339,13 +339,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 db3d697e05..21dfc4ae2c 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -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; @@ -1876,27 +1879,16 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA break; } - case WM_ACTIVATE: // Watch For Window Activate Message - { - windows[window_id].minimized = HIWORD(wParam) != 0; - - if (LOWORD(wParam) == WA_ACTIVE || LOWORD(wParam) == WA_CLICKACTIVE) { - _send_window_event(windows[window_id], WINDOW_EVENT_FOCUS_IN); - windows[window_id].window_focused = true; - alt_mem = false; - control_mem = false; - shift_mem = false; - } else { // WM_INACTIVE - Input::get_singleton()->release_pressed_events(); - _send_window_event(windows[window_id], WINDOW_EVENT_FOCUS_OUT); - windows[window_id].window_focused = false; - alt_mem = false; - }; + case WM_ACTIVATE: { // Watch For Window Activate Message + if (!windows[window_id].window_focused) { + _process_activate_event(window_id, wParam, lParam); + } else { + windows[window_id].saved_wparam = wParam; + windows[window_id].saved_lparam = lParam; - if ((OS::get_singleton()->get_current_tablet_driver() == "wintab") && wintab_available && windows[window_id].wtctx) { - wintab_WTEnable(windows[window_id].wtctx, GET_WM_ACTIVATE_STATE(wParam, lParam)); + // Run a timer to prevent event catching warning if the focused window is closing. + windows[window_id].focus_timer_id = SetTimer(windows[window_id].hWnd, 2, USER_TIMER_MINIMUM, (TIMERPROC) nullptr); } - return 0; // Return To The Message Loop } case WM_GETMINMAXINFO: { @@ -1937,6 +1929,9 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA case WM_CLOSE: // Did We Receive A Close Message? { + if (windows[window_id].focus_timer_id != 0U) { + KillTimer(windows[window_id].hWnd, windows[window_id].focus_timer_id); + } _send_window_event(windows[window_id], WINDOW_EVENT_CLOSE_REQUEST); return 0; // Jump Back @@ -2619,17 +2614,21 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA case WM_ENTERSIZEMOVE: { Input::get_singleton()->release_pressed_events(); - move_timer_id = SetTimer(windows[window_id].hWnd, 1, USER_TIMER_MINIMUM, (TIMERPROC) nullptr); + windows[window_id].move_timer_id = SetTimer(windows[window_id].hWnd, 1, USER_TIMER_MINIMUM, (TIMERPROC) nullptr); } break; case WM_EXITSIZEMOVE: { - KillTimer(windows[window_id].hWnd, move_timer_id); + KillTimer(windows[window_id].hWnd, windows[window_id].move_timer_id); } break; case WM_TIMER: { - if (wParam == move_timer_id) { + if (wParam == windows[window_id].move_timer_id) { _process_key_events(); if (!Main::is_iterating()) { Main::iteration(); } + } else if (wParam == windows[window_id].focus_timer_id) { + _process_activate_event(window_id, windows[window_id].saved_wparam, windows[window_id].saved_lparam); + KillTimer(windows[window_id].hWnd, wParam); + windows[window_id].focus_timer_id = 0U; } } break; @@ -2786,6 +2785,25 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { return DefWindowProcW(hWnd, uMsg, wParam, lParam); } +void DisplayServerWindows::_process_activate_event(WindowID p_window_id, WPARAM wParam, LPARAM lParam) { + if (LOWORD(wParam) == WA_ACTIVE || LOWORD(wParam) == WA_CLICKACTIVE) { + _send_window_event(windows[p_window_id], WINDOW_EVENT_FOCUS_IN); + windows[p_window_id].window_focused = true; + alt_mem = false; + control_mem = false; + shift_mem = false; + } else { // WM_INACTIVE + Input::get_singleton()->release_pressed_events(); + _send_window_event(windows[p_window_id], WINDOW_EVENT_FOCUS_OUT); + windows[p_window_id].window_focused = false; + alt_mem = false; + } + + if ((OS::get_singleton()->get_current_tablet_driver() == "wintab") && wintab_available && windows[p_window_id].wtctx) { + wintab_WTEnable(windows[p_window_id].wtctx, GET_WM_ACTIVATE_STATE(wParam, lParam)); + } +} + void DisplayServerWindows::_process_key_events() { for (int i = 0; i < key_event_pos; i++) { KeyEvent &ke = key_event_buffer[i]; @@ -3213,8 +3231,6 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win } #endif - move_timer_id = 1; - //set_ime_active(false); if (!OS::get_singleton()->is_in_low_processor_usage_mode()) { diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index 89dd927304..c8c6a75bf5 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -339,6 +339,14 @@ private: bool no_focus = false; bool window_has_focus = false; + // Used to transfer data between events using timer. + WPARAM saved_wparam; + LPARAM saved_lparam; + + // Timers. + uint32_t move_timer_id = 0U; + uint32_t focus_timer_id = 0U; + HANDLE wtctx; LOGCONTEXTW wtlc; int min_pressure; @@ -387,8 +395,6 @@ private: WindowID last_focused_window = INVALID_WINDOW_ID; - uint32_t move_timer_id; - HCURSOR hCursor; WNDPROC user_proc = nullptr; @@ -411,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); @@ -424,6 +430,7 @@ private: void _set_mouse_mode_impl(MouseMode p_mode); + void _process_activate_event(WindowID p_window_id, WPARAM wParam, LPARAM lParam); void _process_key_events(); static void _dispatch_input_events(const Ref<InputEvent> &p_event); 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/os_windows.cpp b/platform/windows/os_windows.cpp index 051b69e8d9..fe007027da 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -39,8 +39,6 @@ #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" @@ -177,9 +175,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 +405,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 +432,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 +474,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; }; diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index 78258f132b..1a8791196b 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -136,7 +136,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..8a6bd5f6b6 100644 --- a/scene/2d/animated_sprite_2d.cpp +++ b/scene/2d/animated_sprite_2d.cpp @@ -712,15 +712,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..68d5b4b540 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_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), 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, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_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("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..ae1c1e449a 100644 --- a/scene/2d/audio_stream_player_2d.cpp +++ b/scene/2d/audio_stream_player_2d.cpp @@ -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..6fb8cc414c 100644 --- a/scene/2d/audio_stream_player_2d.h +++ b/scene/2d/audio_stream_player_2d.h @@ -47,32 +47,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; + volatile int output_count = 0; + volatile bool output_ready = false; //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; + volatile float setseek = -1.0; + volatile bool active = false; + volatile 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 +83,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..853e92780b 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -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..3a7d01901d 100644 --- a/scene/2d/camera_2d.h +++ b/scene/2d/camera_2d.h @@ -51,32 +51,32 @@ 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(); @@ -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; + Camera2DProcessMode process_mode = CAMERA2D_PROCESS_IDLE; Size2 _get_camera_screen_size() const; 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..4d1d274542 100644 --- a/scene/2d/collision_shape_2d.cpp +++ b/scene/2d/collision_shape_2d.cpp @@ -125,7 +125,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 +141,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 +154,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 +215,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 +243,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..b34a9a9ea4 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -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; } @@ -1365,34 +1369,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 +1389,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/joints_2d.cpp b/scene/2d/joints_2d.cpp index 1a31f72a59..80445e7e5d 100644 --- a/scene/2d/joints_2d.cpp +++ b/scene/2d/joints_2d.cpp @@ -249,8 +249,6 @@ void Joint2D::_bind_methods() { } Joint2D::Joint2D() { - bias = 0; - exclude_from_collision = true; } /////////////////////////////////////////////////////////////////////////////// @@ -300,7 +298,6 @@ void PinJoint2D::_bind_methods() { } PinJoint2D::PinJoint2D() { - softness = 0; } /////////////////////////////////////////////////////////////////////////////// @@ -364,8 +361,6 @@ void GrooveJoint2D::_bind_methods() { } GrooveJoint2D::GrooveJoint2D() { - length = 50; - initial_offset = 25; } /////////////////////////////////////////////////////////////////////////////// @@ -467,8 +462,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..887155c6ea 100644 --- a/scene/2d/joints_2d.h +++ b/scene/2d/joints_2d.h @@ -43,9 +43,9 @@ 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; String warning; protected: @@ -80,7 +80,7 @@ public: class PinJoint2D : public Joint2D { GDCLASS(PinJoint2D, Joint2D); - real_t softness; + real_t softness = 0.0; protected: void _notification(int p_what); @@ -97,8 +97,8 @@ 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); @@ -118,10 +118,10 @@ 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); diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index ba4372f040..c000c8ea19 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); } 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..2959ea1a36 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 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/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp index 72dc8bd9ad..7360fce330 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; 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..8c103a1239 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(); } 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..ecb354ad15 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]; } @@ -649,13 +649,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..48e44e01a1 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++) { @@ -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..d1a3c01266 100644 --- a/scene/2d/sprite_2d.cpp +++ b/scene/2d/sprite_2d.cpp @@ -462,16 +462,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..33c238d455 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -1872,32 +1872,6 @@ void TileMap::_changed_callback(Object *p_changed, const char *p_prop) { } 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); } diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index b1e54aafae..cfed4c0743 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); diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp index 04a1aedcd3..fccf126dad 100644 --- a/scene/2d/touch_screen_button.cpp +++ b/scene/2d/touch_screen_button.cpp @@ -399,11 +399,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..21a2561dd0 100644 --- a/scene/2d/visibility_notifier_2d.cpp +++ b/scene/2d/visibility_notifier_2d.cpp @@ -363,6 +363,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..99c5276636 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_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), 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, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_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("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..fa8408ba5b 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; @@ -1002,31 +1002,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..33ed758749 100644 --- a/scene/3d/audio_stream_player_3d.h +++ b/scene/3d/audio_stream_player_3d.h @@ -71,46 +71,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; + volatile int output_count = 0; + volatile bool output_ready = false; //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; + volatile float setseek = -1.0; + volatile bool active = false; + volatile 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 +115,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..7c05878710 100644 --- a/scene/3d/baked_lightmap.cpp +++ b/scene/3d/baked_lightmap.cpp @@ -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..fa9da6898c 100644 --- a/scene/3d/camera_3d.cpp +++ b/scene/3d/camera_3d.cpp @@ -653,24 +653,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); } @@ -882,16 +868,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..06bb55e23c 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: @@ -191,13 +192,13 @@ public: }; private: - ProcessMode process_mode; + ProcessMode process_mode = 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; diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp index f1d7ac64b2..b7da4822e2 100644 --- a/scene/3d/collision_object_3d.cpp +++ b/scene/3d/collision_object_3d.cpp @@ -325,10 +325,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 +357,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..b7473ca12a 100644 --- a/scene/3d/collision_object_3d.h +++ b/scene/3d/collision_object_3d.h @@ -37,33 +37,28 @@ 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 { 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; void _update_pickable(); diff --git a/scene/3d/collision_polygon_3d.cpp b/scene/3d/collision_polygon_3d.cpp index 5e77937533..4d117f02d3 100644 --- a/scene/3d/collision_polygon_3d.cpp +++ b/scene/3d/collision_polygon_3d.cpp @@ -132,13 +132,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; } @@ -197,10 +197,5 @@ void CollisionPolygon3D::_bind_methods() { } 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..cb0aba67b1 100644 --- a/scene/3d/collision_polygon_3d.h +++ b/scene/3d/collision_polygon_3d.h @@ -39,14 +39,14 @@ class CollisionPolygon3D : public Node3D { GDCLASS(CollisionPolygon3D, Node3D); 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 +59,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; diff --git a/scene/3d/collision_shape_3d.cpp b/scene/3d/collision_shape_3d.cpp index 47966c772b..928a46aba5 100644 --- a/scene/3d/collision_shape_3d.cpp +++ b/scene/3d/collision_shape_3d.cpp @@ -93,7 +93,6 @@ void CollisionShape3D::_notification(int p_what) { if (shape.is_valid()) { parent->shape_owner_add_shape(owner_id, shape); } - _update_in_shape_owner(); } } break; case NOTIFICATION_ENTER_TREE: { @@ -170,6 +169,9 @@ void CollisionShape3D::_bind_methods() { } 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 +213,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); } diff --git a/scene/3d/collision_shape_3d.h b/scene/3d/collision_shape_3d.h index 5f556b01a9..f55c09ffaa 100644 --- a/scene/3d/collision_shape_3d.h +++ b/scene/3d/collision_shape_3d.h @@ -40,14 +40,14 @@ class CollisionShape3D : public Node3D { Ref<Shape3D> shape; - uint32_t owner_id; - CollisionObject3D *parent; + uint32_t owner_id = 0; + CollisionObject3D *parent = nullptr; - Node *debug_shape; + Node *debug_shape = nullptr; bool debug_shape_dirty; void resource_changed(RES res); - bool disabled; + bool disabled = false; protected: void _update_debug_shape(); diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp index 3562f7b778..48fdeb051d 100644 --- a/scene/3d/cpu_particles_3d.cpp +++ b/scene/3d/cpu_particles_3d.cpp @@ -646,6 +646,8 @@ void CPUParticles3D::_particles_process(float p_delta) { restart = true; } + float tv = 0.0; + if (restart) { if (!emitting) { p.active = false; @@ -660,12 +662,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 +678,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 +708,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 +774,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 +860,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 +892,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 +916,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; } @@ -1440,13 +1445,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 +1452,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); @@ -1483,23 +1466,6 @@ CPUParticles3D::CPUParticles3D() { 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_box_extents(Vector3(1, 1, 1)); - - set_gravity(Vector3(0, -9.8, 0)); - - for (int i = 0; i < PARAM_MAX; i++) { - set_param_randomness(Parameter(i), 0); - } - - for (int i = 0; i < PARTICLE_FLAG_MAX; i++) { - particle_flags[i] = false; - } - - can_update = false; - - set_color(Color(1, 1, 1, 1)); } CPUParticles3D::~CPUParticles3D() { diff --git a/scene/3d/cpu_particles_3d.h b/scene/3d/cpu_particles_3d.h index 3ee03ff3d8..d650bf95ac 100644 --- a/scene/3d/cpu_particles_3d.h +++ b/scene/3d/cpu_particles_3d.h @@ -78,30 +78,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 +110,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 +118,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 +127,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; + volatile bool can_update = false; - 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..1cdea37dad 100644 --- a/scene/3d/decal.cpp +++ b/scene/3d/decal.cpp @@ -220,18 +220,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..1f00eab092 100644 --- a/scene/3d/gi_probe.cpp +++ b/scene/3d/gi_probe.cpp @@ -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(); } @@ -520,7 +509,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 +542,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_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..e6e23b927a 100644 --- a/scene/3d/light_3d.cpp +++ b/scene/3d/light_3d.cpp @@ -212,6 +212,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 +261,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 +324,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 +347,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..9029b5b028 100644 --- a/scene/3d/mesh_instance_3d.cpp +++ b/scene/3d/mesh_instance_3d.cpp @@ -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; @@ -429,7 +428,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..a9acaefc65 100644 --- a/scene/3d/navigation_region_3d.cpp +++ b/scene/3d/navigation_region_3d.cpp @@ -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"); } diff --git a/scene/3d/navigation_region_3d.h b/scene/3d/navigation_region_3d.h index a5b8c2cd5e..e966523b64 100644 --- a/scene/3d/navigation_region_3d.h +++ b/scene/3d/navigation_region_3d.h @@ -46,7 +46,7 @@ class NavigationRegion3D : public Node3D { Navigation3D *navigation = nullptr; Node *debug_view = nullptr; - Thread *bake_thread = nullptr; + Thread bake_thread; protected: void _notification(int p_what); diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index 503dd5735b..57bead022b 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -239,8 +239,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); } @@ -330,7 +330,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) { @@ -364,7 +364,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 { 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..367dd7ec91 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; } @@ -330,8 +330,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 +825,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 +906,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 +1000,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 +1072,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 +1113,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 +1162,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 +1203,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 +1693,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 +1853,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); @@ -2381,11 +2366,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 { 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..624587cce4 100644 --- a/scene/3d/physics_joint_3d.cpp +++ b/scene/3d/physics_joint_3d.cpp @@ -114,21 +114,23 @@ void Joint3D::_update_joint(bool p_only_free) { return; } - if (!body_a) { - SWAP(body_a, body_b); - } - warning = String(); update_configuration_warning(); - joint = _configure_joint(body_a, body_b); + if (body_a) { + joint = _configure_joint(body_a, body_b); + } else if (body_b) { + joint = _configure_joint(body_b, nullptr); + } ERR_FAIL_COND_MSG(!joint.is_valid(), "Failed to configure the joint."); 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,8 +245,6 @@ void Joint3D::_bind_methods() { } Joint3D::Joint3D() { - exclude_from_collision = true; - solver_priority = 1; set_notify_transform(true); } @@ -263,7 +263,7 @@ 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()) { @@ -271,7 +271,7 @@ void PinJoint3D::set_param(Param p_param, float 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]; } @@ -304,19 +304,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,7 +361,7 @@ 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()) { @@ -371,7 +371,7 @@ void HingeJoint3D::set_param(Param p_param, float 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]; } @@ -435,19 +435,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,7 +512,7 @@ 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()) { @@ -521,7 +521,7 @@ void SliderJoint3D::set_param(Param p_param, float 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]; } @@ -577,19 +577,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,7 +618,7 @@ 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()) { @@ -628,7 +628,7 @@ void ConeTwistJoint3D::set_param(Param p_param, float 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]; } @@ -669,51 +669,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,7 +875,7 @@ 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()) { @@ -885,12 +885,12 @@ void Generic6DOFJoint3D::set_param_x(Param p_param, float 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()) { @@ -899,12 +899,12 @@ void Generic6DOFJoint3D::set_param_y(Param p_param, float 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()) { @@ -913,7 +913,7 @@ void Generic6DOFJoint3D::set_param_z(Param p_param, float 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]; } diff --git a/scene/3d/physics_joint_3d.h b/scene/3d/physics_joint_3d.h index 9702076318..914ac3c392 100644 --- a/scene/3d/physics_joint_3d.h +++ b/scene/3d/physics_joint_3d.h @@ -44,8 +44,8 @@ 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; protected: @@ -91,13 +91,13 @@ public: }; protected: - float params[3]; + real_t params[3]; virtual RID _configure_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 +127,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; 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 +184,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]; + real_t params[PARAM_MAX]; virtual RID _configure_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 +217,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]; + real_t params[PARAM_MAX]; virtual RID _configure_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 +277,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; 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..74f7fe2b52 100644 --- a/scene/3d/reflection_probe.cpp +++ b/scene/3d/reflection_probe.cpp @@ -257,20 +257,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..ac2e9bf871 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -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.h b/scene/3d/soft_body_3d.h index d3c5dc022f..288deb0673 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,9 +91,9 @@ 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(); 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..f178daad42 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); } @@ -1109,8 +1095,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..3c35c0ce97 100644 --- a/scene/3d/vehicle_body_3d.h +++ b/scene/3d/vehicle_body_3d.h @@ -42,51 +42,51 @@ 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; + bool m_isInContact = false; PhysicsBody3D *m_groundObject; //could be general void* ptr } m_raycastInfo; @@ -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..68a275684b 100644 --- a/scene/3d/visibility_notifier_3d.cpp +++ b/scene/3d/visibility_notifier_3d.cpp @@ -80,13 +80,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 +112,6 @@ void VisibilityNotifier3D::_bind_methods() { } VisibilityNotifier3D::VisibilityNotifier3D() { - aabb = AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2)); set_notify_transform(true); } @@ -249,6 +251,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..61591cfd10 100644 --- a/scene/3d/visual_instance_3d.cpp +++ b/scene/3d/visual_instance_3d.cpp @@ -135,7 +135,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 +370,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 +411,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/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..b80ae30f1a 100644 --- a/scene/animation/animation_blend_space_2d.cpp +++ b/scene/animation/animation_blend_space_2d.cpp @@ -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..4a0e9e99be 100644 --- a/scene/animation/animation_blend_tree.cpp +++ b/scene/animation/animation_blend_tree.cpp @@ -125,9 +125,6 @@ void AnimationNodeAnimation::_bind_methods() { } AnimationNodeAnimation::AnimationNodeAnimation() { - last_version = 0; - skip = false; - time = "time"; } //////////////////////////////////////////////////////// @@ -346,21 +343,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 +387,8 @@ void AnimationNodeAdd2::_bind_methods() { } AnimationNodeAdd2::AnimationNodeAdd2() { - add_amount = "add_amount"; add_input("in"); add_input("add"); - sync = false; } //////////////////////////////////////////////// @@ -454,11 +434,9 @@ void AnimationNodeAdd3::_bind_methods() { } AnimationNodeAdd3::AnimationNodeAdd3() { - add_amount = "add_amount"; add_input("-add"); add_input("in"); add_input("+add"); - sync = false; } ///////////////////////////////////////////// @@ -504,10 +482,8 @@ void AnimationNodeBlend2::_bind_methods() { } AnimationNodeBlend2::AnimationNodeBlend2() { - blend_amount = "blend_amount"; add_input("in"); add_input("blend"); - sync = false; } ////////////////////////////////////// @@ -583,7 +559,6 @@ void AnimationNodeTimeScale::_bind_methods() { } AnimationNodeTimeScale::AnimationNodeTimeScale() { - scale = "scale"; add_input("in"); } @@ -620,7 +595,6 @@ void AnimationNodeTimeSeek::_bind_methods() { AnimationNodeTimeSeek::AnimationNodeTimeSeek() { add_input("in"); - seek_pos = "seek_position"; } ///////////////////////////////////////////////// @@ -811,16 +785,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); } } diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h index 45a9f2e7e1..4732f43af2 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(); @@ -381,7 +380,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..552e6b6f5d 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; } //////////////////////////////////////////////////////// @@ -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; } /////////////////////////////////////////////////////// @@ -975,5 +960,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..7abc6388a1 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; diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 8e50c733ae..c6554462f7 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -1677,23 +1677,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..c04eeeca68 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; @@ -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,48 +179,37 @@ 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; + AnimationProcessMode animation_process_mode = ANIMATION_PROCESS_IDLE; + AnimationMethodCallMode method_call_mode = ANIMATION_METHOD_CALL_DEFERRED; + bool processing = false; + bool active = true; NodePath root; @@ -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); diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index e6abbc0c7a..0f0cdc67f4 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -441,9 +441,6 @@ void AnimationNode::_bind_methods() { } AnimationNode::AnimationNode() { - state = nullptr; - parent = nullptr; - filter_enabled = false; } //////////////////// @@ -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 @@ -1506,13 +1504,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..0f78b1f0e2 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); @@ -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; + AnimationProcessMode process_mode = 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; diff --git a/scene/animation/root_motion_view.cpp b/scene/animation/root_motion_view.cpp index 5fd936df8e..a4a1b02a4c 100644 --- a/scene/animation/root_motion_view.cpp +++ b/scene/animation/root_motion_view.cpp @@ -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..354f7e5aae 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -1789,12 +1789,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..70d00734f4 100644 --- a/scene/audio/audio_stream_player.cpp +++ b/scene/audio/audio_stream_player.cpp @@ -402,18 +402,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..ab98d41302 100644 --- a/scene/audio/audio_stream_player.h +++ b/scene/audio/audio_stream_player.h @@ -49,22 +49,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; + + volatile float setseek = -1.0; + volatile bool active = false; + volatile bool setstop = false; + volatile bool stop_has_priority = false; + + 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/button.cpp b/scene/gui/button.cpp index 119f3539e1..8b3daf79a8 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -102,8 +102,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 +117,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 +140,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 +160,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 +176,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; @@ -303,13 +303,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); diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index ad21c351d0..6b5d8cb658 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -709,7 +709,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) { @@ -2785,6 +2785,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/file_dialog.cpp b/scene/gui/file_dialog.cpp index 5765d6b932..3a0350b9fb 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) { diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index d5b12b6bb6..d7602bd7cf 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; @@ -401,7 +405,14 @@ 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! } @@ -409,8 +420,14 @@ void GraphEdit::remove_child_notify(Node *p_child) { if (gn) { gn->disconnect("position_offset_changed", callable_mp(this, &GraphEdit::_graph_node_moved)); 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)); + } } } @@ -1576,7 +1593,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 +1608,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); @@ -1741,7 +1758,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); diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 9f5c87377f..6a83042b00 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -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; } diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index 69ca96b28e..bd57817bd3 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) { @@ -886,7 +890,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); @@ -1184,13 +1188,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; @@ -1213,7 +1216,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; diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h index d08823c398..4982a68071 100644 --- a/scene/gui/item_list.h +++ b/scene/gui/item_list.h @@ -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..8fc40955f0 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -184,10 +184,10 @@ 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(); @@ -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; diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 39ea6ed87b..51f780462f 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -121,13 +121,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(); @@ -584,7 +578,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { if (handled) { accept_event(); - } else if (!k->get_command() || (k->get_command() && k->get_alt())) { + } else if (!k->get_command()) { if (k->get_unicode() >= 32 && k->get_keycode() != KEY_DELETE) { if (editable) { selection_delete(); @@ -635,10 +629,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 +771,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. @@ -839,9 +840,9 @@ void LineEdit::_notification(int p_what) { 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 +954,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) { @@ -1407,6 +1401,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 { diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h index 1e7495e734..6db7a78f61 100644 --- a/scene/gui/line_edit.h +++ b/scene/gui/line_edit.h @@ -306,6 +306,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..8e972438a5 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; diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index 4f274595a2..e4c1f94b31 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"); diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index ecb5ac0ffc..b2ebb91500 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -72,9 +72,7 @@ Size2 PopupMenu::_get_contents_minimum_size() const { } size.width += items[i].text_buf->get_size().x; - if (i > 0) { - size.height += vseparation; - } + size.height += vseparation; if (items[i].accel || (items[i].shortcut.is_valid() && items[i].shortcut->is_valid())) { int accel_w = hseparation * 2; @@ -152,9 +150,7 @@ int PopupMenu::_get_mouse_over(const Point2 &p_over) const { } for (int i = 0; i < items.size(); i++) { - if (i > 0) { - ofs.y += vseparation; - } + ofs.y += i > 0 ? vseparation : (float)vseparation / 2; ofs.y += MAX(items[i].get_icon_size().height, items[i].text_buf->get_size().y); @@ -475,10 +471,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; @@ -506,10 +502,8 @@ void PopupMenu::_draw_items() { // Loop through all items and draw each. for (int i = 0; i < items.size(); i++) { - // If not the first item, add the separation space between items. - if (i > 0) { - ofs.y += vseparation; - } + // For the first item only add half a separation. For all other items, add a whole separation to the offset. + ofs.y += i > 0 ? vseparation : (float)vseparation / 2; _shape_item(i); @@ -519,9 +513,9 @@ void PopupMenu::_draw_items() { if (i == mouse_over) { if (rtl) { - hover->draw(ci, Rect2(item_ofs + Point2(-hseparation + scroll_width, -vseparation / 2), Size2(display_width + hseparation * 2, h + vseparation))); + hover->draw(ci, Rect2(item_ofs + Point2(scroll_width, -vseparation / 2), Size2(display_width, h + vseparation))); } else { - hover->draw(ci, Rect2(item_ofs + Point2(-hseparation, -vseparation / 2), Size2(display_width + hseparation * 2, h + vseparation))); + hover->draw(ci, Rect2(item_ofs + Point2(0, -vseparation / 2), Size2(display_width, h + vseparation))); } } @@ -581,14 +575,14 @@ void PopupMenu::_draw_items() { 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); + items[i].text_buf->draw(ci, Point2(center, item_ofs.y + Math::floor((h - items[i].text_buf->get_size().y) / 2.0)), 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)); + 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_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)); + 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_disabled_color : (i == mouse_over ? font_hover_color : font_color)); } } @@ -599,7 +593,7 @@ void PopupMenu::_draw_items() { } else { item_ofs.x = display_width - style->get_margin(SIDE_RIGHT) - items[i].accel_text_buf->get_size().x; } - 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, item_ofs + Point2(0, Math::floor((h - items[i].text_buf->get_size().y) / 2.0)), i == mouse_over ? font_hover_color : font_accelerator_color); } // Cache the item vertical offset from the first item and the height @@ -1636,7 +1630,6 @@ void PopupMenu::_bind_methods() { void PopupMenu::popup(const Rect2 &p_bounds) { moved = Vector2(); popup_time_msec = OS::get_singleton()->get_ticks_msec(); - set_as_minsize(); Popup::popup(p_bounds); } diff --git a/scene/gui/range.cpp b/scene/gui/range.cpp index b9ac6d7505..1e33ab0758 100644 --- a/scene/gui/range.cpp +++ b/scene/gui/range.cpp @@ -171,7 +171,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); diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 4f4d5ece4a..6d5905aedc 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -618,11 +618,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 +631,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 +699,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; @@ -790,7 +800,7 @@ void RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ } 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++; } @@ -910,9 +920,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 +932,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 +1078,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) { @@ -1388,17 +1400,18 @@ void RichTextLabel::_notification(int p_what) { Color base_color = get_theme_color("default_color"); Color outline_color = get_theme_color("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++; } @@ -2001,46 +2014,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; @@ -2905,17 +2878,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 +3105,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 +3147,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 +3179,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 +3380,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 { @@ -3716,6 +3722,7 @@ void RichTextLabel::set_percent_visible(float p_percent) { } main->first_invalid_line = 0; //invalidate ALL _validate_line_caches(main); + _change_notify("visible_characters"); update(); } } @@ -3821,6 +3828,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); @@ -3851,6 +3859,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 +3940,15 @@ 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; + } + } + _change_notify("percent_visible"); update(); } diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index f828a8cd1a..037839dac7 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -337,6 +337,7 @@ private: bool updating_scroll; int current_idx = 1; int current_char_ofs = 0; + int visible_paragraph_count; int visible_line_count; int tab_size; @@ -393,7 +394,7 @@ private: 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; @@ -421,8 +422,6 @@ 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); @@ -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; diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp index 037a60810e..32c878205e 100644 --- a/scene/gui/spin_box.cpp +++ b/scene/gui/spin_box.cpp @@ -280,7 +280,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..a4e3d644e2 100644 --- a/scene/gui/spin_box.h +++ b/scene/gui/spin_box.h @@ -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; + bool allowed = false; + bool enabled = false; Vector2 capture_pos; - float diff_y; + float diff_y = 0; } drag; void _line_edit_focus_exit(); diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp index 7f0d7b6e7b..5acc789fbb 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); } } @@ -655,15 +655,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; @@ -789,6 +789,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)); @@ -1127,13 +1131,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(); } diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp index 3bf71d6c01..c156b1e6f8 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,12 +268,12 @@ 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"); Vector2 size = get_size(); bool rtl = is_layout_rtl(); @@ -316,13 +316,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) { @@ -652,8 +652,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 +683,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 +918,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 +937,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()) { diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index f54e5d1dd7..9285314abe 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -637,7 +637,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 +810,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 +877,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 +918,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; @@ -1001,7 +1001,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); @@ -1230,7 +1230,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 +1238,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); @@ -1249,8 +1250,8 @@ void TextEdit::_notification(int p_what) { 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,38 +1260,42 @@ 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); - } - 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 (glyphs[j].font_rid != RID()) { @@ -1307,11 +1312,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 @@ -1321,7 +1328,9 @@ void TextEdit::_notification(int p_what) { 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); + 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; @@ -1346,7 +1355,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); @@ -1440,78 +1449,97 @@ void TextEdit::_notification(int p_what) { } 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); @@ -1551,11 +1579,11 @@ void TextEdit::_notification(int p_what) { 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; @@ -1563,7 +1591,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; @@ -2268,7 +2296,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)) { @@ -3619,7 +3647,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { return; } - if (!keycode_handled && (!k->get_command() || (k->get_command() && k->get_alt()))) { // For German keyboards. + if (!keycode_handled && !k->get_command()) { // For German keyboards. if (k->get_unicode() >= 32) { if (readonly) { @@ -4894,8 +4922,8 @@ void TextEdit::_update_caches() { 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"); diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index d5b9b46fe2..dc811059c8 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -485,8 +485,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; diff --git a/scene/gui/texture_button.cpp b/scene/gui/texture_button.cpp index 23c48b0906..bd670555ea 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); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index a968a83dad..0049b54f50 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"); @@ -1433,7 +1433,7 @@ 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 icon_col = p_item->cells[i].icon_color; if (p_item->cells[i].dirty) { diff --git a/scene/gui/tree.h b/scene/gui/tree.h index dfc02f760d..2136bada0b 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -459,7 +459,7 @@ 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; diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h index 04e5fda919..64eb3f4e0a 100644 --- a/scene/main/canvas_item.h +++ b/scene/main/canvas_item.h @@ -149,7 +149,7 @@ public: static void finish_shaders(); static void flush_changes(); - RID get_shader_rid() const; + virtual RID get_shader_rid() const override; virtual Shader::Mode get_shader_mode() const override; diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp index ddcf07c8e9..4c6b85d78b 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -163,7 +163,7 @@ Error HTTPRequest::request_raw(const String &p_url, const Vector<String> &p_cust thread_done = false; thread_request_quit = false; client->set_blocking_mode(true); - thread = Thread::create(_thread_func, this); + thread.start(_thread_func, this); } else { client->set_blocking_mode(false); err = _request(); @@ -209,9 +209,7 @@ void HTTPRequest::cancel_request() { set_process_internal(false); } else { thread_request_quit = true; - Thread::wait_to_finish(thread); - memdelete(thread); - thread = nullptr; + thread.wait_to_finish(); } if (file) { @@ -640,8 +638,6 @@ void HTTPRequest::_bind_methods() { } HTTPRequest::HTTPRequest() { - thread = nullptr; - port = 80; redirections = 0; max_redirects = 8; diff --git a/scene/main/http_request.h b/scene/main/http_request.h index 6f606296e4..9dbf561cd4 100644 --- a/scene/main/http_request.h +++ b/scene/main/http_request.h @@ -110,7 +110,7 @@ private: volatile bool thread_done; volatile bool 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..0c01516032 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -1920,32 +1920,22 @@ String Node::get_editor_description() const { 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); -} - -void Node::set_editable_instances(const HashMap<NodePath, int> &p_editable_instances) { - data.editable_instances = p_editable_instances; -} - -HashMap<NodePath, int> Node::get_editable_instances() const { - return data.editable_instances; + return p_node->data.editable_instance; } void Node::set_scene_instance_state(const Ref<SceneState> &p_state) { @@ -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) { @@ -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); diff --git a/scene/main/node.h b/scene/main/node.h index fc7590c5a4..a0dca75791 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -88,8 +88,6 @@ private: Ref<SceneState> instance_state; Ref<SceneState> inherited_state; - HashMap<NodePath, int> editable_instances; - Node *parent = nullptr; Node *owner = nullptr; Vector<Node *> children; @@ -136,6 +134,7 @@ private: bool use_placeholder = false; bool display_folded = false; + bool editable_instance = false; mutable NodePath *path_cache = nullptr; @@ -325,8 +324,6 @@ 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; /* NOTIFICATIONS */ diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index f18ac3b801..1c9d81e87c 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -1372,6 +1372,26 @@ SceneTree::SceneTree() { bool snap_2d_vertices = GLOBAL_DEF("rendering/quality/2d/snap_2d_vertices_to_pixel", false); root->set_snap_2d_vertices_to_pixel(snap_2d_vertices); + int shadowmap_size = GLOBAL_DEF("rendering/quality/shadow_atlas/size", 4096); + 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/size.mobile", 2048); + bool shadowmap_16_bits = GLOBAL_DEF("rendering/quality/shadow_atlas/16_bits", true); + int atlas_q0 = GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_0_subdiv", 2); + int atlas_q1 = GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_1_subdiv", 2); + int atlas_q2 = GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_2_subdiv", 3); + int atlas_q3 = 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")); + + 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/quality/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))); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index c3404078db..82053e1557 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1416,18 +1416,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); @@ -1538,7 +1546,7 @@ void Viewport::_gui_show_tooltip() { gui.tooltip_control, gui.tooltip_control->get_global_transform().xform_inv(gui.last_mouse_pos), &tooltip_owner); - tooltip_text.strip_edges(); + tooltip_text = tooltip_text.strip_edges(); if (tooltip_text.is_empty()) { return; // Nothing to show. } @@ -1580,7 +1588,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 +1603,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); @@ -3479,6 +3489,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); @@ -3546,6 +3559,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 +3617,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); @@ -3656,7 +3674,10 @@ Viewport::Viewport() { physics_has_last_mousepos = false; physics_last_mousepos = Vector2(Math_INF, Math_INF); - shadow_atlas_size = 0; + shadow_atlas_16_bits = true; + shadow_atlas_size = 2048; + set_shadow_atlas_size(shadow_atlas_size); + for (int i = 0; i < 4; i++) { shadow_atlas_quadrant_subdiv[i] = SHADOW_ATLAS_QUADRANT_SUBDIV_MAX; } diff --git a/scene/main/viewport.h b/scene/main/viewport.h index f0818a9fed..17d4835c63 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -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 { @@ -293,6 +297,7 @@ private: DebugDraw debug_draw; int shadow_atlas_size; + bool shadow_atlas_16_bits = true; ShadowAtlasQuadrantSubdiv shadow_atlas_quadrant_subdiv[4]; MSAA msaa; @@ -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; diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index b809eea43b..b14c44689e 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"); diff --git a/scene/resources/capsule_shape_2d.cpp b/scene/resources/capsule_shape_2d.cpp index 6041f4a8b0..63d90a8364 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); } } diff --git a/scene/resources/circle_shape_2d.cpp b/scene/resources/circle_shape_2d.cpp index ba49587d9d..a44c1b68bf 100644 --- a/scene/resources/circle_shape_2d.cpp +++ b/scene/resources/circle_shape_2d.cpp @@ -71,8 +71,9 @@ 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; diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index dad5622117..a0b65e9799 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -46,7 +46,7 @@ static TexCacheMap *tex_cache; static float scale = 1; 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,12 @@ 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<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 +147,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 +186,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,8 +208,8 @@ 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_constant("underline_spacing", "LinkButton", 2 * scale); @@ -216,9 +225,9 @@ 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_constant("hseparation", "ColorPickerButton", 2 * scale); @@ -253,9 +262,9 @@ 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_constant("hseparation", "OptionButton", 2 * scale); theme->set_constant("arrow_margin", "OptionButton", 2 * scale); @@ -272,9 +281,9 @@ 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_constant("hseparation", "MenuButton", 3 * scale); @@ -307,10 +316,10 @@ 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_constant("hseparation", "CheckBox", 4 * scale); theme->set_constant("check_vadjust", "CheckBox", 0 * scale); @@ -344,10 +353,10 @@ 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_constant("hseparation", "CheckButton", 4 * scale); theme->set_constant("check_vadjust", "CheckButton", 0 * scale); @@ -359,8 +368,8 @@ 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); @@ -378,12 +387,12 @@ 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("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); @@ -397,8 +406,8 @@ 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)); // TextEdit @@ -417,12 +426,12 @@ 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("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)); @@ -457,12 +466,12 @@ 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("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)); @@ -598,10 +607,10 @@ 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_constant("hseparation", "PopupMenu", 4 * scale); theme->set_constant("vseparation", "PopupMenu", 4 * scale); @@ -671,12 +680,12 @@ 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("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); @@ -701,8 +710,8 @@ 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("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); @@ -716,8 +725,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 +740,17 @@ 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_constant("side_margin", "TabContainer", 8 * scale); theme->set_constant("icon_separation", "TabContainer", 4 * scale); // 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,9 +765,9 @@ 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_constant("hseparation", "Tabs", 4 * scale); @@ -817,7 +826,7 @@ 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_constant("shadow_offset_x", "TooltipLabel", 1); theme->set_constant("shadow_offset_y", "TooltipLabel", 1); @@ -840,10 +849,10 @@ 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_constant("shadow_offset_x", "RichTextLabel", 1 * scale); theme->set_constant("shadow_offset_y", "RichTextLabel", 1 * scale); 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..8827da1fc4 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -797,7 +797,7 @@ 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) { @@ -854,13 +854,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 @@ -1317,8 +1324,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 +1337,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 diff --git a/scene/resources/environment.h b/scene/resources/environment.h index 1676a28b39..6eb0e0607e 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -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 @@ -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/material.cpp b/scene/resources/material.cpp index a5ec9fcba5..92d2fb1c6d 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -36,6 +36,7 @@ #include "editor/editor_settings.h" #endif +#include "scene/main/scene_tree.h" #include "scene/scene_string_names.h" void Material::set_next_pass(const Ref<Material> &p_pass) { @@ -80,6 +81,14 @@ void Material::_validate_property(PropertyInfo &property) const { } } +void Material::inspect_native_shader_code() { + SceneTree *st = Object::cast_to<SceneTree>(OS::get_singleton()->get_main_loop()); + RID shader = get_shader_rid(); + if (st && shader.is_valid()) { + st->call_group("_native_shader_source_visualizer", "_inspect_shader", shader); + } +} + void Material::_bind_methods() { ClassDB::bind_method(D_METHOD("set_next_pass", "next_pass"), &Material::set_next_pass); ClassDB::bind_method(D_METHOD("get_next_pass"), &Material::get_next_pass); @@ -87,6 +96,9 @@ void Material::_bind_methods() { ClassDB::bind_method(D_METHOD("set_render_priority", "priority"), &Material::set_render_priority); ClassDB::bind_method(D_METHOD("get_render_priority"), &Material::get_render_priority); + ClassDB::bind_method(D_METHOD("inspect_native_shader_code"), &Material::inspect_native_shader_code); + ClassDB::set_method_flags(get_class_static(), _scs_create("inspect_native_shader_code"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR); + ADD_PROPERTY(PropertyInfo(Variant::INT, "render_priority", PROPERTY_HINT_RANGE, itos(RENDER_PRIORITY_MIN) + "," + itos(RENDER_PRIORITY_MAX) + ",1"), "set_render_priority", "get_render_priority"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "next_pass", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_next_pass", "get_next_pass"); @@ -260,6 +272,13 @@ Shader::Mode ShaderMaterial::get_shader_mode() const { return Shader::MODE_SPATIAL; } } +RID ShaderMaterial::get_shader_rid() const { + if (shader.is_valid()) { + return shader->get_rid(); + } else { + return RID(); + } +} ShaderMaterial::ShaderMaterial() { } @@ -716,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]) { diff --git a/scene/resources/material.h b/scene/resources/material.h index a2183a65e4..0048b43c8b 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -47,6 +47,8 @@ class Material : public Resource { Ref<Material> next_pass; int render_priority; + void inspect_native_shader_code(); + protected: _FORCE_INLINE_ RID _get_material() const { return material; } static void _bind_methods(); @@ -66,6 +68,7 @@ public: int get_render_priority() const; virtual RID get_rid() const override; + virtual RID get_shader_rid() const = 0; virtual Shader::Mode get_shader_mode() const = 0; Material(); @@ -100,6 +103,8 @@ public: virtual Shader::Mode get_shader_mode() const override; + virtual RID get_shader_rid() const override; + ShaderMaterial(); ~ShaderMaterial(); }; @@ -736,7 +741,7 @@ public: static RID get_material_rid_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass, bool p_billboard = false, bool p_billboard_y = false); - RID get_shader_rid() const; + virtual RID get_shader_rid() const override; virtual Shader::Mode get_shader_mode() const override; diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 32fede1e5f..e812ad3a01 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -1565,6 +1565,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 +1609,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 +1622,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() { diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index 2f25ecd60b..1fd45c880a 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -176,6 +176,7 @@ class ArrayMesh : public Mesh { Array _get_surfaces() const; void _set_surfaces(const Array &p_data); + Ref<ArrayMesh> shadow_mesh; private: struct Surface { @@ -259,6 +260,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/particles_material.cpp b/scene/resources/particles_material.cpp index 73b7a5cfe9..c5a295e13f 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 += " }"; } diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h index e699a8fb6d..49b48a01b7 100644 --- a/scene/resources/particles_material.h +++ b/scene/resources/particles_material.h @@ -340,7 +340,7 @@ public: void set_sub_emitter_keep_velocity(bool p_enable); bool get_sub_emitter_keep_velocity() const; - RID get_shader_rid() const; + virtual RID get_shader_rid() const override; virtual Shader::Mode get_shader_mode() const override; diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index a6e9e7b5d2..398bce0602 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -304,8 +304,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 +343,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 +383,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)); @@ -769,8 +769,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 +809,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 +845,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); @@ -1458,8 +1458,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)); 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/sky_material.h b/scene/resources/sky_material.h index 6f9dfbee4a..8fe015519d 100644 --- a/scene/resources/sky_material.h +++ b/scene/resources/sky_material.h @@ -89,7 +89,7 @@ public: float get_sun_curve() const; virtual Shader::Mode get_shader_mode() const override; - RID get_shader_rid() const; + virtual RID get_shader_rid() const override; ProceduralSkyMaterial(); ~ProceduralSkyMaterial(); @@ -114,7 +114,7 @@ public: Ref<Texture2D> get_panorama() const; virtual Shader::Mode get_shader_mode() const override; - RID get_shader_rid() const; + virtual RID get_shader_rid() const override; PanoramaSkyMaterial(); ~PanoramaSkyMaterial(); @@ -180,7 +180,7 @@ public: Ref<Texture2D> get_night_sky() const; virtual Shader::Mode get_shader_mode() const override; - RID get_shader_rid() const; + virtual RID get_shader_rid() const override; PhysicalSkyMaterial(); ~PhysicalSkyMaterial(); diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index 93bab1b042..7504a05a49 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -395,10 +395,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 +576,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); } diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h index 53ce72790a..c133f0c825 100644 --- a/scene/resources/style_box.h +++ b/scene/resources/style_box.h @@ -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; diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index c1c87be42d..dbf5268762 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) { diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h index dcb689bfc0..ea6069e7c1 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 { 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/texture.cpp b/scene/resources/texture.cpp index 342a97fd85..9a987ae8b1 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -2136,20 +2136,11 @@ AnimatedTexture::AnimatedTexture() { 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); - } } /////////////////////////////// diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 3bbce050f7..83ef0c44ae 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -745,7 +745,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 { diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 2e2077d811..72724d5ee1 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]; @@ -1605,6 +1622,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); diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index 3c59a922fc..9396a53e8b 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -152,6 +152,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; diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index 7629f435a5..d6200059f6 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,31 @@ 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_FLOAT: + return PORT_TYPE_SCALAR; + 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 +2765,86 @@ 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_FLOAT: + return PORT_TYPE_SCALAR; + 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 +2942,39 @@ 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_SCALAR: + return PORT_TYPE_SCALAR; + case OP_TYPE_VECTOR: + return PORT_TYPE_VECTOR; + case OP_TYPE_VECTOR_SCALAR: + switch (p_port) { + case 0: + return PORT_TYPE_SCALAR; + case 1: + return PORT_TYPE_VECTOR; + default: + break; + } + 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 +2983,131 @@ 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_SCALAR: + return PORT_TYPE_SCALAR; + 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, 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_SCALAR: + return PORT_TYPE_SCALAR; + case OP_TYPE_VECTOR: + return PORT_TYPE_VECTOR; + case OP_TYPE_VECTOR_SCALAR: + switch (p_port) { + case 0: + return PORT_TYPE_SCALAR; // edge0 + case 1: + return PORT_TYPE_SCALAR; // edge1 + case 2: + return PORT_TYPE_VECTOR; // x + default: + break; + } + 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 +3118,98 @@ 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_SCALAR: + return PORT_TYPE_SCALAR; + 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 +3307,37 @@ 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_SCALAR: + return PORT_TYPE_SCALAR; + case OP_TYPE_VECTOR: + if (p_port == 2) { + return PORT_TYPE_VECTOR; + } + return PORT_TYPE_VECTOR; + case OP_TYPE_VECTOR_SCALAR: + if (p_port == 2) { + return PORT_TYPE_SCALAR; + } + 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 +3347,92 @@ 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_SCALAR: + return PORT_TYPE_SCALAR; + 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 @@ -4842,7 +4910,7 @@ VisualShaderNodeIf::VisualShaderNodeIf() { ////////////// Switch String VisualShaderNodeSwitch::get_caption() const { - return "VectorSwitch"; + return "Switch"; } int VisualShaderNodeSwitch::get_input_port_count() const { @@ -4853,7 +4921,23 @@ 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_FLOAT: + return PORT_TYPE_SCALAR; + 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 +4958,84 @@ 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_FLOAT: + return PORT_TYPE_SCALAR; + 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 +5052,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); } @@ -5379,16 +5511,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/servers/audio/audio_driver_dummy.cpp b/servers/audio/audio_driver_dummy.cpp index 12cadb9301..faddced155 100644 --- a/servers/audio/audio_driver_dummy.cpp +++ b/servers/audio/audio_driver_dummy.cpp @@ -48,7 +48,7 @@ Error AudioDriverDummy::init() { 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/effects/audio_effect_capture.cpp b/servers/audio/effects/audio_effect_capture.cpp new file mode 100644 index 0000000000..f37938eec8 --- /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; +} + +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; +} + +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."); + atomic_add(&base->pushed_frames, p_frame_count); + } else { + atomic_add(&base->discarded_frames, p_frame_count); + } +} + +bool AudioEffectCaptureInstance::process_silence() const { + return true; +} diff --git a/modules/inappstore/in_app_store.h b/servers/audio/effects/audio_effect_capture.h index c66c306319..b154be85de 100644 --- a/modules/inappstore/in_app_store.h +++ b/servers/audio/effects/audio_effect_capture.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* in_app_store.h */ +/* audio_effect_capture.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,50 +28,55 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef IN_APP_STORE_H -#define IN_APP_STORE_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" -#ifdef __OBJC__ -@class GodotProductsDelegate; -@class GodotTransactionsObserver; +class AudioEffectCapture; -typedef GodotProductsDelegate InAppStoreProductDelegate; -typedef GodotTransactionsObserver InAppStoreTransactionObserver; -#else -typedef void InAppStoreProductDelegate; -typedef void InAppStoreTransactionObserver; -#endif +class AudioEffectCaptureInstance : public AudioEffectInstance { + GDCLASS(AudioEffectCaptureInstance, AudioEffectInstance); + friend class AudioEffectCapture; + Ref<AudioEffectCapture> base; -class InAppStore : public Object { - GDCLASS(InAppStore, Object); +public: + virtual void process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) override; + virtual bool process_silence() const override; +}; - static InAppStore *instance; - static void _bind_methods(); +class AudioEffectCapture : public AudioEffect { + GDCLASS(AudioEffectCapture, AudioEffect) + friend class AudioEffectCaptureInstance; - List<Variant> pending_events; + RingBuffer<AudioFrame> buffer; + uint64_t discarded_frames = 0; + uint64_t pushed_frames = 0; + float buffer_length_seconds = 0.1f; + bool buffer_initialized = false; - InAppStoreProductDelegate *products_request_delegate; - InAppStoreTransactionObserver *transactions_observer; +protected: + static void _bind_methods(); 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); + virtual Ref<AudioEffectInstance> instance() override; - void _post_event(Variant p_event); - void _record_purchase(String product_id); + void set_buffer_length(float p_buffer_length_seconds); + float get_buffer_length(); - static InAppStore *get_singleton(); + bool can_get_buffer(int p_frames) const; + PackedVector2Array get_buffer(int p_len); + void clear_buffer(); - InAppStore(); - ~InAppStore(); + 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..76a995eb37 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; 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..b79434e7c2 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; 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..16c6a26595 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; } @@ -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 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/physics_2d/body_pair_2d_sw.cpp b/servers/physics_2d/body_pair_2d_sw.cpp index 6a13453f9f..feced36a2b 100644 --- a/servers/physics_2d/body_pair_2d_sw.cpp +++ b/servers/physics_2d/body_pair_2d_sw.cpp @@ -288,21 +288,17 @@ bool BodyPair2DSW::setup(real_t p_step) { if (A->is_shape_set_as_one_way_collision(shape_A)) { Vector2 direction = xform_A.get_axis(1).normalized(); bool valid = false; - if (B->get_linear_velocity().dot(direction) >= 0) { - for (int i = 0; i < contact_count; i++) { - Contact &c = contacts[i]; - if (!c.reused) { - continue; - } - if (c.normal.dot(direction) > 0) { //greater (normal inverted) - continue; - } - - valid = true; - break; + for (int i = 0; i < contact_count; i++) { + Contact &c = contacts[i]; + if (!c.reused) { + continue; } + if (c.normal.dot(direction) > -CMP_EPSILON) { //greater (normal inverted) + continue; + } + valid = true; + break; } - if (!valid) { collided = false; oneway_disabled = true; @@ -313,19 +309,16 @@ bool BodyPair2DSW::setup(real_t p_step) { if (B->is_shape_set_as_one_way_collision(shape_B)) { Vector2 direction = xform_B.get_axis(1).normalized(); bool valid = false; - if (A->get_linear_velocity().dot(direction) >= 0) { - for (int i = 0; i < contact_count; i++) { - Contact &c = contacts[i]; - if (!c.reused) { - continue; - } - if (c.normal.dot(direction) < 0) { //less (normal ok) - continue; - } - - valid = true; - break; + for (int i = 0; i < contact_count; i++) { + Contact &c = contacts[i]; + if (!c.reused) { + continue; + } + if (c.normal.dot(direction) < CMP_EPSILON) { //less (normal ok) + continue; } + valid = true; + break; } if (!valid) { collided = false; 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/physics_server_2d_sw.cpp b/servers/physics_2d/physics_server_2d_sw.cpp index 85e24ca537..14fcf1520a 100644 --- a/servers/physics_2d/physics_server_2d_sw.cpp +++ b/servers/physics_2d/physics_server_2d_sw.cpp @@ -149,24 +149,19 @@ void PhysicsServer2DSW::_shape_col_cbk(const Vector2 &p_point_A, const Vector2 & return; } + Vector2 rel_dir = (p_point_A - p_point_B); + real_t rel_length2 = rel_dir.length_squared(); if (cbk->valid_dir != Vector2()) { - if (p_point_A.distance_squared_to(p_point_B) > cbk->valid_depth * cbk->valid_depth) { - cbk->invalid_by_dir++; - return; - } - Vector2 rel_dir = (p_point_A - p_point_B).normalized(); - - if (cbk->valid_dir.dot(rel_dir) < Math_SQRT12) { //sqrt(2)/2.0 - 45 degrees - cbk->invalid_by_dir++; - - /* - print_line("A: "+p_point_A); - print_line("B: "+p_point_B); - print_line("discard too angled "+rtos(cbk->valid_dir.dot((p_point_A-p_point_B)))); - print_line("resnorm: "+(p_point_A-p_point_B).normalized()); - print_line("distance: "+rtos(p_point_A.distance_to(p_point_B))); - */ - return; + if (cbk->valid_depth < 10e20) { + if (rel_length2 > cbk->valid_depth * cbk->valid_depth || + (rel_length2 > CMP_EPSILON && cbk->valid_dir.dot(rel_dir.normalized()) < CMP_EPSILON)) { + cbk->invalid_by_dir++; + return; + } + } else { + if (rel_length2 > 0 && cbk->valid_dir.dot(rel_dir.normalized()) < CMP_EPSILON) { + return; + } } } @@ -182,8 +177,7 @@ void PhysicsServer2DSW::_shape_col_cbk(const Vector2 &p_point_A, const Vector2 & } } - real_t d = p_point_A.distance_squared_to(p_point_B); - if (d < min_depth) { + if (rel_length2 < min_depth) { return; } cbk->ptr[min_depth_idx * 2 + 0] = p_point_A; @@ -673,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()); @@ -964,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); diff --git a/servers/physics_2d/physics_server_2d_sw.h b/servers/physics_2d/physics_server_2d_sw.h index 3305c0bd3d..62ea30b3f6 100644 --- a/servers/physics_2d/physics_server_2d_sw.h +++ b/servers/physics_2d/physics_server_2d_sw.h @@ -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,7 +248,7 @@ 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; diff --git a/servers/physics_2d/physics_server_2d_wrap_mt.cpp b/servers/physics_2d/physics_server_2d_wrap_mt.cpp index 15d875b3b7..897724fe6f 100644 --- a/servers/physics_2d/physics_server_2d_wrap_mt.cpp +++ b/servers/physics_2d/physics_server_2d_wrap_mt.cpp @@ -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,7 +97,7 @@ void PhysicsServer2DWrapMT::end_sync() { void PhysicsServer2DWrapMT::init() { if (create_thread) { //OS::get_singleton()->release_rendering_thread(); - thread = Thread::create(_thread_callback, this); + thread.start(_thread_callback, this); while (!step_thread_up) { OS::get_singleton()->delay_usec(1000); } @@ -107,12 +107,9 @@ 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(); } @@ -135,7 +132,6 @@ PhysicsServer2DWrapMT::PhysicsServer2DWrapMT(PhysicsServer2D *p_contained, bool command_queue(p_create_thread) { physics_2d_server = p_contained; create_thread = p_create_thread; - thread = nullptr; step_pending = 0; step_thread_up = false; diff --git a/servers/physics_2d/physics_server_2d_wrap_mt.h b/servers/physics_2d/physics_server_2d_wrap_mt.h index 9207081a51..fbc5b1eaa1 100644 --- a/servers/physics_2d/physics_server_2d_wrap_mt.h +++ b/servers/physics_2d/physics_server_2d_wrap_mt.h @@ -53,7 +53,7 @@ class PhysicsServer2DWrapMT : public PhysicsServer2D { Thread::ID server_thread; Thread::ID main_thread; volatile bool exit; - Thread *thread; + Thread thread; volatile bool step_thread_up; bool create_thread; @@ -189,7 +189,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); @@ -255,7 +255,7 @@ public: 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) { 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); } 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 c2a6dc828e..05136e2501 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -278,9 +278,9 @@ bool PhysicsDirectSpaceState2DSW::cast_motion(const RID &p_shape, const Transfor 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 @@ -376,25 +376,25 @@ struct _RestCallbackData2D { Vector2 best_normal; real_t best_len; Vector2 valid_dir; - real_t valid_depth; real_t min_allowed_depth; }; static void _rest_cbk_result(const Vector2 &p_point_A, const Vector2 &p_point_B, void *p_userdata) { _RestCallbackData2D *rd = (_RestCallbackData2D *)p_userdata; - if (rd->valid_dir != Vector2()) { - if (p_point_A.distance_squared_to(p_point_B) > rd->valid_depth * rd->valid_depth) { - return; - } - if (rd->valid_dir.dot((p_point_A - p_point_B).normalized()) < Math_PI * 0.25) { - return; - } - } - Vector2 contact_rel = p_point_B - p_point_A; real_t len = contact_rel.length(); + if (len == 0) { + return; + } + + Vector2 normal = contact_rel / len; + + if (rd->valid_dir != Vector2() && rd->valid_dir.dot(normal) > -CMP_EPSILON) { + return; + } + if (len < rd->min_allowed_depth) { return; } @@ -405,7 +405,7 @@ static void _rest_cbk_result(const Vector2 &p_point_A, const Vector2 &p_point_B, rd->best_len = len; rd->best_contact = p_point_B; - rd->best_normal = contact_rel / len; + rd->best_normal = normal; rd->best_object = rd->object; rd->best_shape = rd->shape; rd->best_local_shape = rd->local_shape; @@ -440,7 +440,6 @@ bool PhysicsDirectSpaceState2DSW::rest_info(RID p_shape, const Transform2D &p_sh } rcd.valid_dir = Vector2(); - rcd.valid_depth = 0; rcd.object = col_obj; rcd.shape = shape_idx; rcd.local_shape = 0; @@ -643,9 +642,9 @@ int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_t Vector2 a = sr[k * 2 + 0]; Vector2 b = sr[k * 2 + 1]; - recover_motion += (b - a) * 0.4; + 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; @@ -740,7 +739,7 @@ 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 separation_margin = MIN(p_margin, MAX(0.0, p_motion.length() - CMP_EPSILON)); //don't separate by more than the intended motion Transform2D body_transform = p_from; @@ -794,7 +793,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; @@ -805,7 +804,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); } @@ -850,7 +849,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co for (int i = 0; i < cbk.amount; i++) { Vector2 a = sr[i * 2 + 0]; Vector2 b = sr[i * 2 + 1]; - recover_motion += (b - a) * 0.4; + recover_motion += (b - a) / cbk.amount; } if (recover_motion == Vector2()) { @@ -1002,7 +1001,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co best_shape = -1; //no best shape with cast, reset to -1 } - { + if (safe < 1) { //it collided, let's get the rest info in unsafe advance Transform2D ugt = body_transform; ugt.elements[2] += p_motion * unsafe; @@ -1061,10 +1060,8 @@ 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(); - rcd.valid_depth = 10e20; } else { rcd.valid_dir = Vector2(); - rcd.valid_depth = 0; } rcd.object = col_obj; @@ -1331,7 +1328,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/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/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/physics_server_3d_sw.cpp b/servers/physics_3d/physics_server_3d_sw.cpp index 274de8411c..b554a23bf2 100644 --- a/servers/physics_3d/physics_server_3d_sw.cpp +++ b/servers/physics_3d/physics_server_3d_sw.cpp @@ -874,7 +874,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); diff --git a/servers/physics_3d/physics_server_3d_sw.h b/servers/physics_3d/physics_server_3d_sw.h index 9b6b113677..c48db81d97 100644 --- a/servers/physics_3d/physics_server_3d_sw.h +++ b/servers/physics_3d/physics_server_3d_sw.h @@ -235,7 +235,7 @@ public: 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; diff --git a/servers/physics_3d/shape_3d_sw.cpp b/servers/physics_3d/shape_3d_sw.cpp index f2adcc1072..9c37060bea 100644 --- a/servers/physics_3d/shape_3d_sw.cpp +++ b/servers/physics_3d/shape_3d_sw.cpp @@ -261,7 +261,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; } @@ -429,7 +429,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 +442,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; @@ -839,7 +839,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 +852,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; diff --git a/servers/physics_3d/space_3d_sw.cpp b/servers/physics_3d/space_3d_sw.cpp index 2b2b5122da..43cc032120 100644 --- a/servers/physics_3d/space_3d_sw.cpp +++ b/servers/physics_3d/space_3d_sw.cpp @@ -274,11 +274,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 @@ -476,7 +476,7 @@ Vector3 PhysicsDirectSpaceState3DSW::get_closest_point_to_object_volume(RID p_ob 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 +492,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; @@ -649,9 +649,9 @@ int Space3DSW::test_body_ray_separation(Body3DSW *p_body, const Transform &p_tra Vector3 a = sr[k * 2 + 0]; Vector3 b = sr[k * 2 + 1]; - recover_motion += (b - a) * 0.4; + 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; @@ -791,7 +791,7 @@ 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) * 0.4; + recover_motion += (b - a) / cbk.amount; } if (recover_motion == Vector3()) { @@ -1211,7 +1211,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..7c36229e9f 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(); diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h index dd38855199..710eecfdec 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,7 +520,7 @@ 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 */ @@ -576,7 +576,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..a4dc80b0a6 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(); diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h index 303825f37c..1349e0e033 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; @@ -404,8 +404,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 +459,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; @@ -495,7 +495,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,7 +506,7 @@ 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 */ @@ -601,8 +601,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; @@ -631,8 +631,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) = 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 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; @@ -667,8 +667,8 @@ 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 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, @@ -681,8 +681,8 @@ public: 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 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, @@ -722,8 +722,8 @@ public: 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 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) = 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; @@ -741,7 +741,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 flush_queries() = 0; virtual void finish() = 0; diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index 58bcdf5802..50efd7c554 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" @@ -166,6 +167,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..e1ce52661c 100644 --- a/servers/rendering/renderer_canvas_cull.cpp +++ b/servers/rendering/renderer_canvas_cull.cpp @@ -721,8 +721,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; 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 a73eb3782c..a9cadb40df 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(); @@ -992,47 +947,47 @@ void EffectsRD::gather_ssao(RD::ComputeListID p_compute_list, const Vector<RID> ssao.gather_push_constant.pass_coord_offset[0] = i % 2; ssao.gather_push_constant.pass_coord_offset[1] = i / 2; - ssao.gather_push_constant.pass_uv_offset[0] = ((i % 2) - 0.0) / p_settings.screen_size.x; - ssao.gather_push_constant.pass_uv_offset[1] = ((i / 2) - 0.0) / p_settings.screen_size.y; + ssao.gather_push_constant.pass_uv_offset[0] = ((i % 2) - 0.0) / p_settings.full_screen_size.x; + ssao.gather_push_constant.pass_uv_offset[1] = ((i / 2) - 0.0) / p_settings.full_screen_size.y; ssao.gather_push_constant.pass = i; 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.screen_size.x >> (p_settings.half_size ? 2 : 1)) - 1) / 8 + 1; - int y_groups = ((p_settings.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> &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) { +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; { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 0; - u.ids.push_back(depth_mipmaps[1]); + u.ids.push_back(p_depth_mipmaps[1]); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; - u.ids.push_back(depth_mipmaps[2]); + u.ids.push_back(p_depth_mipmaps[2]); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; - u.ids.push_back(depth_mipmaps[3]); + u.ids.push_back(p_depth_mipmaps[3]); uniforms.push_back(u); } ssao.downsample_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.downsample_shader.version_get_shader(ssao.downsample_shader_version, 2), 2); @@ -1051,8 +1006,8 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep ssao.downsample_push_constant.z_near = p_projection.get_z_near(); ssao.downsample_push_constant.z_far = p_projection.get_z_far(); } - ssao.downsample_push_constant.pixel_size[0] = 1.0 / p_settings.screen_size.x; - ssao.downsample_push_constant.pixel_size[1] = 1.0 / p_settings.screen_size.y; + ssao.downsample_push_constant.pixel_size[0] = 1.0 / p_settings.full_screen_size.x; + ssao.downsample_push_constant.pixel_size[1] = 1.0 / p_settings.full_screen_size.y; ssao.downsample_push_constant.radius_sq = p_settings.radius * p_settings.radius; int downsample_pipeline = SSAO_DOWNSAMPLE; @@ -1068,24 +1023,25 @@ 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[downsample_pipeline]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_depth_buffer), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(depth_mipmaps[0]), 1); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_depth_mipmaps[0]), 1); if (p_settings.quality > RS::ENV_SSAO_QUALITY_MEDIUM) { RD::get_singleton()->compute_list_bind_uniform_set(compute_list, ssao.downsample_uniform_set, 2); } RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.downsample_push_constant, sizeof(SSAODownsamplePushConstant)); - int x_groups = (MAX(1, p_settings.screen_size.x >> (p_settings.half_size ? 2 : 1)) - 1) / 8 + 1; - int y_groups = (MAX(1, p_settings.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 { - ssao.gather_push_constant.screen_size[0] = p_settings.screen_size.x; - ssao.gather_push_constant.screen_size[1] = p_settings.screen_size.y; + 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; ssao.gather_push_constant.half_screen_pixel_size[0] = 1.0 / p_settings.half_screen_size.x; ssao.gather_push_constant.half_screen_pixel_size[1] = 1.0 / p_settings.half_screen_size.y; @@ -1122,7 +1078,7 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep ssao.gather_push_constant.inv_radius_near_limit = 1.0f / radius_near_limit; ssao.gather_push_constant.neg_inv_radius = -1.0 / ssao.gather_push_constant.radius; - ssao.gather_push_constant.load_counter_avg_div = 9.0 / float((p_settings.quarter_size.x) * (p_settings.quarter_size.y) * 255); + ssao.gather_push_constant.load_counter_avg_div = 9.0 / float((p_settings.quarter_screen_size.x) * (p_settings.quarter_screen_size.y) * 255); ssao.gather_push_constant.adaptive_sample_limit = p_settings.adaptive_target; ssao.gather_push_constant.detail_intensity = p_settings.detail; @@ -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_size.x - 1) / 8 + 1; - int y_groups = (p_settings.quarter_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,25 +1226,25 @@ 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.screen_size.x >> (p_settings.half_size ? 2 : 1)) - 1) / 8 + 1; - int y_groups = ((p_settings.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.screen_size.x; - ssao.interleave_push_constant.pixel_size[1] = 1.0 / p_settings.screen_size.y; + 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; ssao.interleave_push_constant.size_modifier = uint32_t(p_settings.half_size ? 4 : 2); int interleave_pipeline = SSAO_INTERLEAVE_HALF; @@ -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.screen_size.x - 1) / 8 + 1; - int y_groups = (p_settings.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++; } } @@ -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 ad4a660944..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); @@ -745,9 +731,9 @@ public: float fadeout_from = 50.0; float fadeout_to = 300.0; - Size2i screen_size = Size2i(); + Size2i full_screen_size = Size2i(); Size2i half_screen_size = Size2i(); - Size2i quarter_size = Size2i(); + Size2i quarter_screen_size = Size2i(); }; void tonemapper(RID p_source_color, RID p_dst_framebuffer, const TonemapSettings &p_settings); @@ -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 508d56cfab..2a1a4efe48 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; @@ -2239,6 +2239,11 @@ Variant RendererCanvasRenderRD::ShaderData::get_default_parameter(const StringNa return Variant(); } +RS::ShaderNativeSourceCode RendererCanvasRenderRD::ShaderData::get_native_source_code() const { + RendererCanvasRenderRD *canvas_singleton = (RendererCanvasRenderRD *)RendererCanvasRender::singleton; + return canvas_singleton->shader.canvas_shader.version_get_native_source_code(version); +} + RendererCanvasRenderRD::ShaderData::ShaderData() { valid = false; uses_screen_texture = false; @@ -2489,7 +2494,7 @@ RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) { actions.renames["COLOR"] = "color"; actions.renames["NORMAL"] = "normal"; actions.renames["NORMAL_MAP"] = "normal_map"; - actions.renames["NORMAL_MAP_DEPTH"] = "normal_depth"; + actions.renames["NORMAL_MAP_DEPTH"] = "normal_map_depth"; actions.renames["TEXTURE"] = "color_texture"; actions.renames["TEXTURE_PIXEL_SIZE"] = "draw_data.color_texture_pixel_size"; actions.renames["NORMAL_TEXTURE"] = "normal_texture"; @@ -2501,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"; diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h index 545eeaa106..cb947d7180 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h @@ -188,6 +188,8 @@ class RendererCanvasRenderRD : public RendererCanvasRender { virtual bool is_animated() const; virtual bool casts_shadows() const; virtual Variant get_default_parameter(const StringName &p_parameter) const; + virtual RS::ShaderNativeSourceCode get_native_source_code() const; + ShaderData(); virtual ~ShaderData(); }; diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp index fb9c114ade..be2552bd32 100644 --- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp @@ -154,12 +154,9 @@ void RendererCompositorRD::initialize() { } } -ThreadWorkPool RendererCompositorRD::thread_work_pool; uint64_t RendererCompositorRD::frame = 1; void RendererCompositorRD::finalize() { - thread_work_pool.finish(); - memdelete(scene); memdelete(canvas); memdelete(storage); @@ -174,7 +171,6 @@ RendererCompositorRD *RendererCompositorRD::singleton = nullptr; RendererCompositorRD::RendererCompositorRD() { singleton = this; - thread_work_pool.init(); time = 0; storage = memnew(RendererStorageRD); diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.h b/servers/rendering/renderer_rd/renderer_compositor_rd.h index e1995872af..cb85fc79e0 100644 --- a/servers/rendering/renderer_rd/renderer_compositor_rd.h +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.h @@ -90,8 +90,6 @@ public: virtual bool is_low_end() const { return false; } - static ThreadWorkPool thread_work_pool; - static RendererCompositorRD *singleton; RendererCompositorRD(); ~RendererCompositorRD() {} diff --git a/servers/rendering/renderer_rd/renderer_scene_render_forward.cpp b/servers/rendering/renderer_rd/renderer_scene_render_forward.cpp index 6881d7913f..509495680a 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_forward.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_forward.cpp @@ -394,6 +394,12 @@ Variant RendererSceneRenderForward::ShaderData::get_default_parameter(const Stri return Variant(); } +RS::ShaderNativeSourceCode RendererSceneRenderForward::ShaderData::get_native_source_code() const { + RendererSceneRenderForward *scene_singleton = (RendererSceneRenderForward *)RendererSceneRenderForward::singleton; + + return scene_singleton->shader.scene_shader.version_get_native_source_code(version); +} + RendererSceneRenderForward::ShaderData::ShaderData() { valid = false; uses_screen_texture = false; @@ -447,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(); @@ -577,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; @@ -627,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(); @@ -806,252 +789,92 @@ bool RendererSceneRenderForward::free(RID p_rid) { return false; } -void RendererSceneRenderForward::_fill_instances(RenderList::Element **p_elements, int p_element_count, bool p_for_depth, bool p_has_sdfgi, bool p_has_opaque_gi) { - uint32_t lightmap_captures_used = 0; - - for (int i = 0; i < p_element_count; i++) { - const RenderList::Element *e = p_elements[i]; - InstanceData &id = scene_state.instances[i]; - bool store_transform = true; - id.flags = 0; - id.mask = e->instance->layer_mask; - id.instance_uniforms_ofs = e->instance->instance_allocated_shader_parameters_offset >= 0 ? e->instance->instance_allocated_shader_parameters_offset : 0; - - if (e->instance->base_type == RS::INSTANCE_MULTIMESH) { - id.flags |= INSTANCE_DATA_FLAG_MULTIMESH; - uint32_t stride; - if (storage->multimesh_get_transform_format(e->instance->base) == RS::MULTIMESH_TRANSFORM_2D) { - id.flags |= INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D; - stride = 2; - } else { - stride = 3; - } - if (storage->multimesh_uses_colors(e->instance->base)) { - id.flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR; - stride += 1; - } - if (storage->multimesh_uses_custom_data(e->instance->base)) { - id.flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA; - stride += 1; - } - - id.flags |= (stride << INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_SHIFT); - } else if (e->instance->base_type == RS::INSTANCE_PARTICLES) { - id.flags |= INSTANCE_DATA_FLAG_MULTIMESH; - uint32_t stride; - if (false) { // 2D particles - id.flags |= INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D; - stride = 2; - } else { - stride = 3; - } - - id.flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR; - stride += 1; - - id.flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA; - stride += 1; - - id.flags |= (stride << INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_SHIFT); - - if (!storage->particles_is_using_local_coords(e->instance->base)) { - store_transform = false; - } - - } else if (e->instance->base_type == RS::INSTANCE_MESH) { - if (e->instance->skeleton.is_valid()) { - id.flags |= INSTANCE_DATA_FLAG_SKELETON; - } - } - - if (store_transform) { - RendererStorageRD::store_transform(e->instance->transform, id.transform); - RendererStorageRD::store_transform(Transform(e->instance->transform.basis.inverse().transposed()), id.normal_transform); - } else { - RendererStorageRD::store_transform(Transform(), id.transform); - RendererStorageRD::store_transform(Transform(), id.normal_transform); - } - - if (p_for_depth) { - id.gi_offset = 0xFFFFFFFF; - continue; - } - - if (e->instance->lightmap) { - int32_t lightmap_index = storage->lightmap_get_array_index(e->instance->lightmap->base); - if (lightmap_index >= 0) { - id.gi_offset = lightmap_index; - id.gi_offset |= e->instance->lightmap_slice_index << 12; - id.gi_offset |= e->instance->lightmap_cull_index << 20; - id.lightmap_uv_scale[0] = e->instance->lightmap_uv_scale.position.x; - id.lightmap_uv_scale[1] = e->instance->lightmap_uv_scale.position.y; - id.lightmap_uv_scale[2] = e->instance->lightmap_uv_scale.size.width; - id.lightmap_uv_scale[3] = e->instance->lightmap_uv_scale.size.height; - id.flags |= INSTANCE_DATA_FLAG_USE_LIGHTMAP; - if (storage->lightmap_uses_spherical_harmonics(e->instance->lightmap->base)) { - id.flags |= INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP; - } - } else { - id.gi_offset = 0xFFFFFFFF; - } - } else if (!e->instance->lightmap_sh.is_empty()) { - if (lightmap_captures_used < scene_state.max_lightmap_captures) { - const Color *src_capture = e->instance->lightmap_sh.ptr(); - LightmapCaptureData &lcd = scene_state.lightmap_captures[lightmap_captures_used]; - for (int j = 0; j < 9; j++) { - lcd.sh[j * 4 + 0] = src_capture[j].r; - lcd.sh[j * 4 + 1] = src_capture[j].g; - lcd.sh[j * 4 + 2] = src_capture[j].b; - lcd.sh[j * 4 + 3] = src_capture[j].a; - } - id.flags |= INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE; - id.gi_offset = lightmap_captures_used; - lightmap_captures_used++; - } - - } else { - if (p_has_opaque_gi) { - id.flags |= INSTANCE_DATA_FLAG_USE_GI_BUFFERS; - } - - if (!low_end && !e->instance->gi_probe_instances.is_empty()) { - uint32_t written = 0; - for (int j = 0; j < e->instance->gi_probe_instances.size(); j++) { - RID probe = e->instance->gi_probe_instances[j]; - - uint32_t index = gi_probe_instance_get_render_index(probe); - - if (written == 0) { - id.gi_offset = index; - id.flags |= INSTANCE_DATA_FLAG_USE_GIPROBE; - written = 1; - } else { - id.gi_offset = index << 16; - written = 2; - break; - } - } - if (written == 0) { - id.gi_offset = 0xFFFFFFFF; - } else if (written == 1) { - id.gi_offset |= 0xFFFF0000; - } - } else { - if (p_has_sdfgi && (e->instance->baked_light || e->instance->dynamic_gi)) { - id.flags |= INSTANCE_DATA_FLAG_USE_SDFGI; - } - id.gi_offset = 0xFFFFFFFF; - } - } - } - - RD::get_singleton()->buffer_update(scene_state.instance_buffer, 0, sizeof(InstanceData) * p_element_count, scene_state.instances, true); - 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); - } -} - /// RENDERING /// -void RendererSceneRenderForward::_render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **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, const Vector2 &p_uv_offset, const Plane &p_lod_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold) { +template <RendererSceneRenderForward::PassMode p_pass_mode> +void RendererSceneRenderForward::_render_list_template(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element) { RD::DrawListID draw_list = p_draw_list; RD::FramebufferFormatID framebuffer_format = p_framebuffer_Format; //global scope bindings RD::get_singleton()->draw_list_bind_uniform_set(draw_list, render_base_uniform_set, SCENE_UNIFORM_SET); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_render_pass_uniform_set, RENDER_PASS_UNIFORM_SET); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_params->render_pass_uniform_set, RENDER_PASS_UNIFORM_SET); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, default_vec4_xform_uniform_set, TRANSFORMS_UNIFORM_SET); - MaterialData *prev_material = nullptr; + RID prev_material_uniform_set; RID prev_vertex_array_rd; RID prev_index_array_rd; RID prev_pipeline_rd; RID prev_xforms_uniform_set; - PushConstant push_constant; - zeromem(&push_constant, sizeof(PushConstant)); - push_constant.bake_uv2_offset[0] = p_uv_offset.x; - push_constant.bake_uv2_offset[1] = p_uv_offset.y; + bool shadow_pass = (p_params->pass_mode == PASS_MODE_SHADOW) || (p_params->pass_mode == PASS_MODE_SHADOW_DP); + + 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 || 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; - for (int i = 0; i < p_element_count; i++) { - const RenderList::Element *e = p_elements[i]; + } else { + material_uniform_set = surf->material_uniform_set; + shader = surf->shader; + mesh_surface = surf->surface; + } - MaterialData *material = e->material; - ShaderData *shader = material->shader_data; - RID xforms_uniform_set; + if (!mesh_surface) { + continue; + } //find cull variant ShaderData::CullVariant cull_variant; - if (p_pass_mode == PASS_MODE_DEPTH_MATERIAL || p_pass_mode == PASS_MODE_SDF || ((p_pass_mode == PASS_MODE_SHADOW || p_pass_mode == PASS_MODE_SHADOW_DP) && e->instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED)) { + if (p_params->pass_mode == PASS_MODE_DEPTH_MATERIAL || p_params->pass_mode == PASS_MODE_SDF || ((p_params->pass_mode == PASS_MODE_SHADOW || p_params->pass_mode == PASS_MODE_SHADOW_DP) && surf->flags & GeometryInstanceSurfaceDataCache::FLAG_USES_DOUBLE_SIDED_SHADOWS)) { cull_variant = ShaderData::CULL_VARIANT_DOUBLE_SIDED; } else { - bool mirror = e->instance->mirror; - if (p_reverse_cull) { + bool mirror = surf->owner->mirror; + if (p_params->reverse_cull) { mirror = !mirror; } cull_variant = mirror ? ShaderData::CULL_VARIANT_REVERSED : ShaderData::CULL_VARIANT_NORMAL; } - //find primitive and vertex format - RS::PrimitiveType primitive; - void *mesh_surface = nullptr; - - switch (e->instance->base_type) { - case RS::INSTANCE_MESH: { - mesh_surface = storage->mesh_get_surface(e->instance->base, e->surface_index); - - primitive = storage->mesh_surface_get_primitive(mesh_surface); - if (e->instance->skeleton.is_valid()) { - xforms_uniform_set = storage->skeleton_get_3d_uniform_set(e->instance->skeleton, default_shader_rd, TRANSFORMS_UNIFORM_SET); - } - } break; - case RS::INSTANCE_MULTIMESH: { - RID mesh = storage->multimesh_get_mesh(e->instance->base); - ERR_CONTINUE(!mesh.is_valid()); //should be a bug - - mesh_surface = storage->mesh_get_surface(e->instance->base, e->surface_index); - - primitive = storage->mesh_surface_get_primitive(mesh_surface); - - xforms_uniform_set = storage->multimesh_get_3d_uniform_set(e->instance->base, default_shader_rd, TRANSFORMS_UNIFORM_SET); - - } break; - case RS::INSTANCE_IMMEDIATE: { - ERR_CONTINUE(true); //should be a bug - } break; - case RS::INSTANCE_PARTICLES: { - RID mesh = storage->particles_get_draw_pass_mesh(e->instance->base, e->surface_index >> 16); - ERR_CONTINUE(!mesh.is_valid()); //should be a bug - - mesh_surface = storage->mesh_get_surface(e->instance->base, e->surface_index & 0xFFFF); - - primitive = storage->mesh_surface_get_primitive(mesh_surface); - - xforms_uniform_set = storage->particles_get_instance_buffer_uniform_set(e->instance->base, default_shader_rd, TRANSFORMS_UNIFORM_SET); - - } break; - default: { - ERR_CONTINUE(true); //should be a bug - } - } + RS::PrimitiveType primitive = surf->primitive; + RID xforms_uniform_set = surf->owner->transforms_uniform_set; ShaderVersion shader_version = SHADER_VERSION_MAX; // Assigned to silence wrong -Wmaybe-initialized. - switch (p_pass_mode) { + switch (p_params->pass_mode) { case PASS_MODE_COLOR: case PASS_MODE_COLOR_TRANSPARENT: { - if (e->uses_lightmap) { + if (element_info.uses_lightmap) { shader_version = SHADER_VERSION_LIGHTMAP_COLOR_PASS; - } else if (e->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 (e->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; @@ -1086,42 +909,15 @@ void RendererSceneRenderForward::_render_list(RenderingDevice::DrawListID p_draw RID vertex_array_rd; RID index_array_rd; - if (mesh_surface) { - if (e->instance->mesh_instance.is_valid()) { //skeleton and blend shape - storage->mesh_instance_surface_get_vertex_arrays_and_format(e->instance->mesh_instance, e->surface_index, pipeline->get_vertex_input_mask(), vertex_array_rd, vertex_format); - } else { - storage->mesh_surface_get_vertex_arrays_and_format(mesh_surface, pipeline->get_vertex_input_mask(), vertex_array_rd, vertex_format); - } - - if (p_screen_lod_threshold > 0.0 && storage->mesh_surface_has_lod(mesh_surface)) { - Vector3 support_min = e->instance->transformed_aabb.get_support(-p_lod_plane.normal); - Vector3 support_max = e->instance->transformed_aabb.get_support(p_lod_plane.normal); - - float distance_min = p_lod_plane.distance_to(support_min); - float distance_max = p_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; - } - - Vector3 model_scale_vec = e->instance->transform.basis.get_scale_abs(); - - float model_scale = MAX(model_scale_vec.x, MAX(model_scale_vec.y, model_scale_vec.z)); - - index_array_rd = storage->mesh_surface_get_index_array_with_lod(mesh_surface, model_scale * e->instance->lod_bias, distance * p_lod_distance_multiplier, p_screen_lod_threshold); - - } else { - index_array_rd = storage->mesh_surface_get_index_array(mesh_surface); - } + //skeleton and blend shape + if (surf->owner->mesh_instance.is_valid()) { + storage->mesh_instance_surface_get_vertex_arrays_and_format(surf->owner->mesh_instance, surf->surface_index, pipeline->get_vertex_input_mask(), vertex_array_rd, vertex_format); + } else { + storage->mesh_surface_get_vertex_arrays_and_format(mesh_surface, pipeline->get_vertex_input_mask(), vertex_array_rd, vertex_format); } + 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); prev_vertex_array_rd = vertex_array_rd; @@ -1134,7 +930,7 @@ void RendererSceneRenderForward::_render_list(RenderingDevice::DrawListID p_draw prev_index_array_rd = index_array_rd; } - RID pipeline_rd = pipeline->get_render_pipeline(vertex_format, framebuffer_format, p_force_wireframe); + RID pipeline_rd = pipeline->get_render_pipeline(vertex_format, framebuffer_format, p_params->force_wireframe); if (pipeline_rd != prev_pipeline_rd) { // checking with prev shader does not make so much sense, as @@ -1148,40 +944,87 @@ void RendererSceneRenderForward::_render_list(RenderingDevice::DrawListID p_draw prev_xforms_uniform_set = xforms_uniform_set; } - if (material != prev_material) { + if (material_uniform_set != prev_material_uniform_set) { //update uniform set - if (material->uniform_set.is_valid()) { - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, material->uniform_set, MATERIAL_UNIFORM_SET); + if (material_uniform_set.is_valid()) { + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, material_uniform_set, MATERIAL_UNIFORM_SET); } - prev_material = material; + prev_material_uniform_set = material_uniform_set; } - push_constant.index = i; - RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(PushConstant)); + RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(SceneState::PushConstant)); - switch (e->instance->base_type) { - case RS::INSTANCE_MESH: { - RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid()); - } break; - case RS::INSTANCE_MULTIMESH: { - uint32_t instances = storage->multimesh_get_instances_to_draw(e->instance->base); - RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid(), instances); - } break; - case RS::INSTANCE_IMMEDIATE: { - } break; - case RS::INSTANCE_PARTICLES: { - uint32_t instances = storage->particles_get_amount(e->instance->base); - RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid(), instances); - } break; - default: { - ERR_CONTINUE(true); //should be a bug - } - } + 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 } } -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::_render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element) { + //use template for faster performance (pass mode comparisons are inlined) + + switch (p_params->pass_mode) { + case PASS_MODE_COLOR: { + _render_list_template<PASS_MODE_COLOR>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element); + } break; + case PASS_MODE_COLOR_SPECULAR: { + _render_list_template<PASS_MODE_COLOR_SPECULAR>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element); + } break; + case PASS_MODE_COLOR_TRANSPARENT: { + _render_list_template<PASS_MODE_COLOR_TRANSPARENT>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element); + } break; + case PASS_MODE_SHADOW: { + _render_list_template<PASS_MODE_SHADOW>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element); + } break; + case PASS_MODE_SHADOW_DP: { + _render_list_template<PASS_MODE_SHADOW_DP>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element); + } break; + case PASS_MODE_DEPTH: { + _render_list_template<PASS_MODE_DEPTH>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element); + } break; + case PASS_MODE_DEPTH_NORMAL_ROUGHNESS: { + _render_list_template<PASS_MODE_DEPTH_NORMAL_ROUGHNESS>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element); + } break; + case PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE: { + _render_list_template<PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element); + } break; + case PASS_MODE_DEPTH_MATERIAL: { + _render_list_template<PASS_MODE_DEPTH_MATERIAL>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element); + } break; + case PASS_MODE_SDF: { + _render_list_template<PASS_MODE_SDF>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element); + } break; + } +} + +void RendererSceneRenderForward::_render_list_thread_function(uint32_t p_thread, RenderListParameters *p_params) { + uint32_t render_total = p_params->element_count; + uint32_t total_threads = RendererThreadPool::singleton->thread_work_pool.get_thread_count(); + uint32_t render_from = p_thread * render_total / total_threads; + uint32_t render_to = (p_thread + 1 == total_threads) ? render_total : ((p_thread + 1) * render_total / total_threads); + _render_list(thread_draw_lists[p_thread], p_params->framebuffer_format, p_params, render_from, render_to); +} + +void RendererSceneRenderForward::_render_list_with_threads(RenderListParameters *p_params, RID p_framebuffer, RD::InitialAction p_initial_color_action, RD::FinalAction p_final_color_action, RD::InitialAction p_initial_depth_action, RD::FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region, const Vector<RID> &p_storage_textures) { + RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(p_framebuffer); + p_params->framebuffer_format = fb_format; + + if ((uint32_t)p_params->element_count > render_list_thread_threshold && false) { // secondary command buffers need more testing at this time + //multi threaded + 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(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(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 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; @@ -1209,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); @@ -1410,276 +1263,332 @@ 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); -} - -void RendererSceneRenderForward::_add_geometry(InstanceBase *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi) { - RID m_src; - - m_src = p_instance->material_override.is_valid() ? p_instance->material_override : p_material; - - if (unlikely(get_debug_draw_mode() != RS::VIEWPORT_DEBUG_DRAW_DISABLED)) { - if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW) { - m_src = overdraw_material; - } else if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_LIGHTING) { - m_src = default_material; - } - } - - MaterialData *material = nullptr; - - if (m_src.is_valid()) { - material = (MaterialData *)storage->material_get_data(m_src, RendererStorageRD::SHADER_TYPE_3D); - if (!material || !material->shader_data->valid) { - material = nullptr; + 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); +} - if (!material) { - material = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D); - m_src = default_material; - } - - ERR_FAIL_COND(!material); - - _add_geometry_with_material(p_instance, p_surface, material, m_src, p_pass_mode, p_geometry_index, p_using_sdfgi); - - while (material->next_pass.is_valid()) { - material = (MaterialData *)storage->material_get_data(material->next_pass, RendererStorageRD::SHADER_TYPE_3D); - if (!material || !material->shader_data->valid) { - break; +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; } - _add_geometry_with_material(p_instance, p_surface, material, material->next_pass, p_pass_mode, p_geometry_index, p_using_sdfgi); + 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(); -void RendererSceneRenderForward::_add_geometry_with_material(InstanceBase *p_instance, uint32_t p_surface, MaterialData *p_material, RID p_material_rid, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi) { - bool has_read_screen_alpha = p_material->shader_data->uses_screen_texture || p_material->shader_data->uses_depth_texture || p_material->shader_data->uses_normal_texture; - bool has_base_alpha = (p_material->shader_data->uses_alpha || has_read_screen_alpha); - bool has_blend_alpha = p_material->shader_data->uses_blend_alpha; - bool has_alpha = has_base_alpha || has_blend_alpha; + scene_state.instance_data[p_render_list].resize(p_offset + element_total); + rl->element_info.resize(p_offset + element_total); - if (p_material->shader_data->uses_sss) { - scene_state.used_sss = true; - } + 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; - if (p_material->shader_data->uses_screen_texture) { - scene_state.used_screen_texture = true; - } + SceneState::InstanceData &instance_data = scene_state.instance_data[p_render_list][i + p_offset]; - if (p_material->shader_data->uses_depth_texture) { - scene_state.used_depth_texture = true; - } + if (inst->store_transform_cache) { + RendererStorageRD::store_transform(inst->transform, instance_data.transform); + } else { + RendererStorageRD::store_transform(Transform(), instance_data.transform); + } - if (p_material->shader_data->uses_normal_texture) { - scene_state.used_normal_texture = true; - } + 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; - if (p_pass_mode != PASS_MODE_COLOR && p_pass_mode != PASS_MODE_COLOR_SPECULAR) { - if (has_blend_alpha || has_read_screen_alpha || (has_base_alpha && !p_material->shader_data->uses_depth_pre_pass) || p_material->shader_data->depth_draw == ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == ShaderData::DEPTH_TEST_DISABLED || p_instance->cast_shadows == RS::SHADOW_CASTING_SETTING_OFF) { - //conditions in which no depth pass should be processed - return; - } + bool cant_repeat = instance_data.flags & INSTANCE_DATA_FLAG_MULTIMESH || inst->mesh_instance.is_valid(); - if ((p_pass_mode != PASS_MODE_DEPTH_MATERIAL && p_pass_mode != PASS_MODE_SDF) && !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) { - //shader does not use discard and does not write a vertex position, use generic material - if (p_pass_mode == PASS_MODE_SHADOW || p_pass_mode == PASS_MODE_DEPTH) { - p_material = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D); - } else if ((p_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS || p_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE) && !p_material->shader_data->uses_normal && !p_material->shader_data->uses_roughness) { - p_material = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D); + 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; } - has_alpha = false; - } - - has_alpha = has_alpha || p_material->shader_data->depth_test == ShaderData::DEPTH_TEST_DISABLED; + RenderElementInfo &element_info = rl->element_info[p_offset + i]; - RenderList::Element *e = has_alpha ? render_list.add_alpha_element() : render_list.add_element(); + 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 (!e) { - return; + if (cant_repeat) { + prev_surface = nullptr; + } else { + prev_surface = surface; + } } - e->instance = p_instance; - e->material = p_material; - e->surface_index = p_surface; - e->sort_key = 0; - - if (e->material->last_pass != render_pass) { - if (!RD::get_singleton()->uniform_set_is_valid(e->material->uniform_set)) { - //uniform set no longer valid, probably a texture changed - storage->material_force_update_textures(p_material_rid, RendererStorageRD::SHADER_TYPE_3D); - } - e->material->last_pass = render_pass; - e->material->index = scene_state.current_material_index++; - if (e->material->shader_data->last_pass != render_pass) { - e->material->shader_data->last_pass = scene_state.current_material_index++; - e->material->shader_data->index = scene_state.current_shader_index++; + if (repeats > 0) { + for (uint32_t j = 1; j <= repeats; j++) { + rl->element_info[p_offset + element_total - j].repeat = j; } } - e->geometry_index = p_geometry_index; - e->material_index = e->material->index; - e->uses_instancing = e->instance->base_type == RS::INSTANCE_MULTIMESH; - e->uses_lightmap = e->instance->lightmap != nullptr || !e->instance->lightmap_sh.is_empty(); - e->uses_forward_gi = has_alpha && (e->instance->gi_probe_instances.size() || p_using_sdfgi); - e->shader_index = e->shader_index; - e->depth_layer = e->instance->depth_layer; - e->priority = p_material->priority; - if (p_material->shader_data->uses_time) { - RenderingServerDefault::redraw_request(); + if (p_update_buffer) { + _update_instance_data_buffer(p_render_list); } } -void RendererSceneRenderForward::_fill_render_list(const PagedArray<InstanceBase *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_using_sdfgi) { - scene_state.current_shader_index = 0; - scene_state.current_material_index = 0; - 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::_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 geometry_index = 0; + RenderList *rl = &render_list[p_render_list]; + _update_dirty_geometry_instances(); + + if (!p_append) { + rl->clear(); + if (p_render_list == RENDER_LIST_OPAQUE) { + render_list[RENDER_LIST_ALPHA].clear(); //opaque fills alpha too + } + } //fill list for (int i = 0; i < (int)p_instances.size(); i++) { - InstanceBase *inst = p_instances[i]; + GeometryInstanceForward *inst = static_cast<GeometryInstanceForward *>(p_instances[i]); - inst->depth = near_plane.distance_to(inst->transform.origin); - inst->depth_layer = CLAMP(int(inst->depth * 16 / z_max), 0, 15); + Vector3 support_min = inst->transformed_aabb.get_support(-near_plane.normal); + inst->depth = near_plane.distance_to(support_min); + uint32_t depth_layer = CLAMP(int(inst->depth * 16 / z_max), 0, 15); - //add geometry for drawing - switch (inst->base_type) { - case RS::INSTANCE_MESH: { - const RID *materials = nullptr; - uint32_t surface_count; + uint32_t flags = inst->base_flags; //fill flags if appropriate - materials = storage->mesh_get_surface_count_and_materials(inst->base, surface_count); - if (!materials) { - continue; //nothing to do - } + bool uses_lightmap = false; + bool uses_gi = false; - const RID *inst_materials = inst->materials.ptr(); + if (p_render_list == RENDER_LIST_OPAQUE) { + //setup GI - for (uint32_t j = 0; j < surface_count; j++) { - RID material = inst_materials[j].is_valid() ? inst_materials[j] : materials[j]; + if (inst->lightmap_instance.is_valid()) { + int32_t lightmap_cull_index = -1; + for (uint32_t j = 0; j < scene_state.lightmaps_used; j++) { + if (scene_state.lightmap_ids[j] == inst->lightmap_instance) { + lightmap_cull_index = j; + break; + } + } + if (lightmap_cull_index >= 0) { + 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->gi_offset_cache = 0xFFFFFFFF; + } - uint32_t surface_index = storage->mesh_surface_get_render_pass_index(inst->base, j, render_pass, &geometry_index); - _add_geometry(inst, j, material, p_pass_mode, surface_index, p_using_sdfgi); + } else if (inst->lightmap_sh) { + if (lightmap_captures_used < scene_state.max_lightmap_captures) { + const Color *src_capture = inst->lightmap_sh->sh; + LightmapCaptureData &lcd = scene_state.lightmap_captures[lightmap_captures_used]; + for (int j = 0; j < 9; j++) { + lcd.sh[j * 4 + 0] = src_capture[j].r; + lcd.sh[j * 4 + 1] = src_capture[j].g; + lcd.sh[j * 4 + 2] = src_capture[j].b; + lcd.sh[j * 4 + 3] = src_capture[j].a; + } + flags |= INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE; + inst->gi_offset_cache = lightmap_captures_used; + lightmap_captures_used++; + uses_lightmap = true; } - //mesh->last_pass=frame; + } else if (!low_end) { + if (p_using_opaque_gi) { + flags |= INSTANCE_DATA_FLAG_USE_GI_BUFFERS; + } - } break; + if (inst->gi_probes[0].is_valid()) { + uint32_t probe0_index = 0xFFFF; + uint32_t probe1_index = 0xFFFF; - case RS::INSTANCE_MULTIMESH: { - if (storage->multimesh_get_instances_to_draw(inst->base) == 0) { - //not visible, 0 instances - continue; - } + for (uint32_t j = 0; j < scene_state.giprobes_used; j++) { + if (scene_state.giprobe_ids[j] == inst->gi_probes[0]) { + probe0_index = j; + } else if (scene_state.giprobe_ids[j] == inst->gi_probes[1]) { + probe1_index = j; + } + } - RID mesh = storage->multimesh_get_mesh(inst->base); - if (!mesh.is_valid()) { - continue; + if (probe0_index == 0xFFFF && probe1_index != 0xFFFF) { + //0 must always exist if a probe exists + SWAP(probe0_index, probe1_index); + } + + 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->gi_offset_cache = 0xFFFFFFFF; } + } + } + inst->flags_cache = flags; - const RID *materials = nullptr; - uint32_t surface_count; + GeometryInstanceSurfaceDataCache *surf = inst->surface_caches; - materials = storage->mesh_get_surface_count_and_materials(mesh, surface_count); - if (!materials) { - continue; //nothing to do - } + while (surf) { + surf->sort.uses_forward_gi = 0; + surf->sort.uses_lightmap = 0; - for (uint32_t j = 0; j < surface_count; j++) { - uint32_t surface_index = storage->mesh_surface_get_multimesh_render_pass_index(mesh, j, render_pass, &geometry_index); - _add_geometry(inst, j, materials[j], p_pass_mode, surface_index, p_using_sdfgi); - } + // LOD - } break; -#if 0 - case RS::INSTANCE_IMMEDIATE: { - RasterizerStorageGLES3::Immediate *immediate = storage->immediate_owner.getornull(inst->base); - ERR_CONTINUE(!immediate); + 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); - _add_geometry(immediate, inst, nullptr, -1, p_depth_pass, p_shadow_pass); + float distance_min = p_lod_plane.distance_to(lod_support_min); + float distance_max = p_lod_plane.distance_to(lod_support_max); - } break; -#endif - case RS::INSTANCE_PARTICLES: { - int draw_passes = storage->particles_get_draw_passes(inst->base); + float distance = 0.0; - for (int j = 0; j < draw_passes; j++) { - RID mesh = storage->particles_get_draw_pass_mesh(inst->base, j); - if (!mesh.is_valid()) - continue; + 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; + } - const RID *materials = nullptr; - uint32_t surface_count; + 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; + } - materials = storage->mesh_get_surface_count_and_materials(mesh, surface_count); - if (!materials) { - continue; //nothing to do + // ADD Element + if (p_pass_mode == PASS_MODE_COLOR) { + if (surf->flags & (GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH | GeometryInstanceSurfaceDataCache::FLAG_PASS_OPAQUE)) { + rl->add_element(surf); + } + if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_PASS_ALPHA) { + render_list[RENDER_LIST_ALPHA].add_element(surf); + if (uses_gi) { + surf->sort.uses_forward_gi = 1; } + } - for (uint32_t k = 0; k < surface_count; k++) { - uint32_t surface_index = storage->mesh_surface_get_particles_render_pass_index(mesh, j, render_pass, &geometry_index); - _add_geometry(inst, (j << 16) | k, materials[j], p_pass_mode, surface_index, p_using_sdfgi); - } + if (uses_lightmap) { + surf->sort.uses_lightmap = 1; } - } break; + if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_USES_SUBSURFACE_SCATTERING) { + scene_state.used_sss = true; + } + if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_USES_SCREEN_TEXTURE) { + scene_state.used_screen_texture = true; + } + if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_USES_NORMAL_TEXTURE) { + scene_state.used_normal_texture = true; + } + if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_USES_DEPTH_TEXTURE) { + scene_state.used_depth_texture = true; + } - default: { + } else if (p_pass_mode == PASS_MODE_SHADOW || p_pass_mode == PASS_MODE_SHADOW_DP) { + if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_PASS_SHADOW) { + rl->add_element(surf); + } + } else { + if (surf->flags & (GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH | GeometryInstanceSurfaceDataCache::FLAG_PASS_OPAQUE)) { + rl->add_element(surf); + } } + + surf->sort.depth_layer = depth_layer; + + surf = surf->next; } } + + 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); + } +} + +void RendererSceneRenderForward::_setup_giprobes(const PagedArray<RID> &p_giprobes) { + scene_state.giprobes_used = MIN(p_giprobes.size(), uint32_t(MAX_GI_PROBES)); + for (uint32_t i = 0; i < scene_state.giprobes_used; i++) { + scene_state.giprobe_ids[i] = p_giprobes[i]; + } } -void RendererSceneRenderForward::_setup_lightmaps(const PagedArray<InstanceBase *> &p_lightmaps, const Transform &p_cam_transform) { - uint32_t lightmaps_used = 0; +void RendererSceneRenderForward::_setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform &p_cam_transform) { + scene_state.lightmaps_used = 0; for (int i = 0; i < (int)p_lightmaps.size(); i++) { if (i >= (int)scene_state.max_lightmaps) { break; } - InstanceBase *lm = p_lightmaps[i]; - Basis to_lm = lm->transform.basis.inverse() * p_cam_transform.basis; + RID lightmap = lightmap_instance_get_lightmap(p_lightmaps[i]); + + Basis to_lm = lightmap_instance_get_transform(p_lightmaps[i]).basis.inverse() * p_cam_transform.basis; to_lm = to_lm.inverse().transposed(); //will transform normals RendererStorageRD::store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform); - lm->lightmap_cull_index = i; - lightmaps_used++; + scene_state.lightmap_ids[i] = p_lightmaps[i]; + scene_state.lightmap_has_sh[i] = storage->lightmap_uses_spherical_harmonics(lightmap); + + scene_state.lightmaps_used++; } - if (lightmaps_used > 0) { - RD::get_singleton()->buffer_update(scene_state.lightmap_buffer, 0, sizeof(LightmapData) * lightmaps_used, scene_state.lightmaps, true); + 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, 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<InstanceBase *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<InstanceBase *> &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)); @@ -1692,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; @@ -1709,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; @@ -1718,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) { @@ -1728,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; } @@ -1767,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; @@ -1783,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_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_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_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) - render_list.clear(); - _fill_render_list(p_instances, PASS_MODE_COLOR, p_cam_projection, p_cam_transform, using_sdfgi); + _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; @@ -1849,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; @@ -1866,58 +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); - - _fill_instances(render_list.elements, render_list.element_count, false, false, using_sdfgi || using_giprobe); - 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>()); + 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; - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(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); - _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(depth_framebuffer), 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); - RD::get_singleton()->draw_list_end(); + 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); + 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; @@ -1938,17 +1868,17 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf } RID framebuffer = using_separate_specular ? opaque_specular_framebuffer : opaque_framebuffer; - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(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); - _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(framebuffer), 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); - RD::get_singleton()->draw_list_end(); - + 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 - draw_list = 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); + 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); RD::get_singleton()->draw_list_end(); } } + 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); @@ -1958,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(); } @@ -1973,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(); } @@ -1986,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"); @@ -2019,119 +1958,161 @@ 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"); - render_list.sort_by_reverse_depth_and_priority(true); + 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); - _fill_instances(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, false, using_sdfgi); + _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); { - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(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); - _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(alpha_framebuffer), &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); - RD::get_singleton()->draw_list_end(); + 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<InstanceBase *> &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; } - render_list.clear(); - 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); - RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>()); + { + //regular forward for now + bool flip_cull = p_use_dp_flip; + if (p_flip_y) { + flip_cull = !flip_cull; + } - RENDER_TIMESTAMP("Render Shadow"); + 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_list.sort_by_key(false); + 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; - _fill_instances(render_list.elements, render_list.element_count, true); + 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 - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ); - _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), 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); - RD::get_singleton()->draw_list_end(); + scene_state.shadow_passes.push_back(shadow_pass); } } -void RendererSceneRenderForward::_render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<InstanceBase *> &p_instances) { - RENDER_TIMESTAMP("Setup Render Collider Heightfield"); +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) - _update_render_base_uniform_set(); + 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); + } - render_pass++; + 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"); - scene_state.ubo.dual_paraboloid_side = 0; + 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); + } - _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); + 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(); +} - render_list.clear(); +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"); - PassMode pass_mode = PASS_MODE_SHADOW; + RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield"); - _fill_render_list(p_instances, pass_mode, p_cam_projection, p_cam_transform); + _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), 1, 32, RID(), true, Color(), 0, p_cam_projection.get_z_far(), false, false); - RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>()); + PassMode pass_mode = PASS_MODE_SHADOW; - RENDER_TIMESTAMP("Render Collider Heightield"); + _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); - render_list.sort_by_key(false); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>()); - _fill_instances(render_list.elements, render_list.element_count, true); + RENDER_TIMESTAMP("Render Collider Heightfield"); { //regular forward for now - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ); - _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_fb), render_list.elements, render_list.element_count, false, pass_mode, true, rp_uniform_set); - RD::get_singleton()->draw_list_end(); + 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<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +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; - - _setup_environment(RID(), RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), RID(), false, Color(), 0, 0); + scene_state.ubo.material_uv2_mode = false; - render_list.clear(); + _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>()); + 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); - - _fill_instances(render_list.elements, render_list.element_count, 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); //regular forward for now Vector<Color> clear; clear.push_back(Color(0, 0, 0, 0)); @@ -2140,37 +2121,36 @@ void RendererSceneRenderForward::_render_material(const Transform &p_cam_transfo clear.push_back(Color(0, 0, 0, 0)); clear.push_back(Color(0, 0, 0, 0)); RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, clear, 1.0, 0, p_region); - _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), render_list.elements, render_list.element_count, true, pass_mode, true, rp_uniform_set); + _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<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +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); - - render_list.clear(); + _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>()); + 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); - - _fill_instances(render_list.elements, render_list.element_count, 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)); @@ -2198,31 +2178,32 @@ void RendererSceneRenderForward::_render_uv2(const PagedArray<InstanceBase *> &p Vector2 ofs = uv_offsets[i]; ofs.x /= p_region.size.width; ofs.y /= p_region.size.height; - _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), render_list.elements, render_list.element_count, true, pass_mode, true, rp_uniform_set, true, ofs); //first wireframe, for pseudo conservative + render_list_params.uv_offset = ofs; + _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), &render_list_params, 0, render_list_params.element_count); //first wireframe, for pseudo conservative } - _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), render_list.elements, render_list.element_count, true, pass_mode, true, rp_uniform_set, false); //second regular triangles + render_list_params.uv_offset = Vector2(); + _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), &render_list_params, 0, render_list_params.element_count); //second regular triangles 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<InstanceBase *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) { +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++; - render_list.clear(); - PassMode pass_mode = PASS_MODE_SDF; - _fill_render_list(p_instances, pass_mode, CameraMatrix(), Transform()); - render_list.sort_by_key(false); - _fill_instances(render_list.elements, render_list.element_count, true); - - 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; @@ -2273,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) { @@ -2281,10 +2264,11 @@ void RendererSceneRenderForward::_render_sdfgi(RID p_render_buffers, const Vecto E = sdfgi_framebuffer_size_cache.insert(fb_size, fb); } - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(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); - _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(E->get()), render_list.elements, render_list.element_count, true, pass_mode, true, rp_uniform_set, false); //second regular triangles - RD::get_singleton()->draw_list_end(); + 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() { @@ -2336,15 +2320,15 @@ 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 = 4; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(scene_state.instance_buffer); + u.ids.push_back(get_spot_light_buffer()); uniforms.push_back(u); } @@ -2352,48 +2336,33 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() { RD::Uniform u; u.binding = 5; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(get_positional_light_buffer()); - uniforms.push_back(u); - } - - { - RD::Uniform u; - u.binding = 6; - 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.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids = storage->lightmap_array_get_textures(); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 12; + 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 = 13; + u.binding = 9; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID decal_atlas = storage->decal_atlas_get_texture(); u.ids.push_back(decal_atlas); @@ -2401,7 +2370,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() { } { RD::Uniform u; - u.binding = 14; + 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); @@ -2409,7 +2378,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() { } { RD::Uniform u; - u.binding = 15; + u.binding = 11; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(get_decal_buffer()); uniforms.push_back(u); @@ -2417,35 +2386,8 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() { { RD::Uniform u; - u.binding = 16; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.push_back(get_cluster_builder_texture()); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 17; 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 = 18; - 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 = 19; + u.binding = 12; u.ids.push_back(storage->global_variables_get_storage_buffer()); uniforms.push_back(u); } @@ -2453,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 = 20; + u.binding = 13; u.ids.push_back(sdfgi_get_ubo()); uniforms.push_back(u); } @@ -2462,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) { - 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()) { @@ -2477,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; @@ -2484,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); @@ -2493,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); @@ -2505,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()) { @@ -2517,10 +2476,39 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff u.ids.push_back(texture); uniforms.push_back(u); } + { + RD::Uniform u; + 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); + for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) { + if (i < p_lightmaps.size()) { + RID base = lightmap_instance_get_lightmap(p_lightmaps[i]); + RID texture = storage->lightmap_get_texture(base); + RID rd_texture = storage->texture_get_rd_texture(texture); + u.ids.write[i] = rd_texture; + } else { + u.ids.write[i] = default_tex; + } + } + uniforms.push_back(u); + } { RD::Uniform u; - u.binding = 3; + 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); @@ -2541,7 +2529,16 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff { RD::Uniform u; - u.binding = 4; + 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); @@ -2549,17 +2546,18 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff } { RD::Uniform u; - u.binding = 5; + 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 = 6; + 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); @@ -2568,7 +2566,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff { RD::Uniform u; - u.binding = 7; + 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); @@ -2578,24 +2576,26 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff { RD::Uniform u; - u.binding = 8; + 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 = 9; + 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 = 10; + u.binding = 15; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID t; if (rb && render_buffers_is_sdfgi_enabled(p_render_buffers)) { @@ -2608,7 +2608,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff } { RD::Uniform u; - u.binding = 11; + 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)); @@ -2619,14 +2619,14 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff } { RD::Uniform u; - u.binding = 12; + 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 = 13; + u.binding = 18; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID vfog = RID(); if (rb && render_buffers_has_volumetric_fog(p_render_buffers)) { @@ -2642,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) { @@ -2654,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); @@ -2667,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); @@ -2676,7 +2698,7 @@ 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); @@ -2684,9 +2706,33 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed } { + // 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); + uniforms.push_back(u); + } + + { + // No Lightmaps + 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); + for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) { + u.ids.write[i] = default_tex; + } + + uniforms.push_back(u); + } + + { // No GIProbes RD::Uniform u; - u.binding = 3; + 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); @@ -2696,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 = 4; + 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 = 5; + 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 = 6; + 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 = 7; + u.binding = 12; u.ids.push_back(p_geom_facing_texture); uniforms.push_back(u); } @@ -2746,23 +2802,530 @@ 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); +RendererSceneRenderForward *RendererSceneRenderForward::singleton = nullptr; - return rb->ambient_buffer; +void RendererSceneRenderForward::set_time(double p_time, double p_step) { + time = p_time; + RendererSceneRenderRD::set_time(p_time, p_step); } -RID RendererSceneRenderForward::_render_buffers_get_reflection_texture(RID p_render_buffers) { - RenderBufferDataForward *rb = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers); +void RendererSceneRenderForward::_geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance) { + GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance); + if (ginstance->dirty_list_element.in_list()) { + return; + } + + //clear surface caches + GeometryInstanceSurfaceDataCache *surf = ginstance->surface_caches; + + while (surf) { + GeometryInstanceSurfaceDataCache *next = surf->next; + geometry_instance_surface_alloc.free(surf); + surf = next; + } + + ginstance->surface_caches = nullptr; - return rb->reflection_buffer; + geometry_instance_dirty_list.add(&ginstance->dirty_list_element); } -RendererSceneRenderForward *RendererSceneRenderForward::singleton = nullptr; +void RendererSceneRenderForward::_geometry_instance_add_surface_with_material(GeometryInstanceForward *ginstance, uint32_t p_surface, MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh) { + bool has_read_screen_alpha = p_material->shader_data->uses_screen_texture || p_material->shader_data->uses_depth_texture || p_material->shader_data->uses_normal_texture; + bool has_base_alpha = (p_material->shader_data->uses_alpha || has_read_screen_alpha); + bool has_blend_alpha = p_material->shader_data->uses_blend_alpha; + bool has_alpha = has_base_alpha || has_blend_alpha; -void RendererSceneRenderForward::set_time(double p_time, double p_step) { - time = p_time; - RendererSceneRenderRD::set_time(p_time, p_step); + uint32_t flags = 0; + + if (p_material->shader_data->uses_sss) { + flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_SUBSURFACE_SCATTERING; + } + + if (p_material->shader_data->uses_screen_texture) { + flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_SCREEN_TEXTURE; + } + + if (p_material->shader_data->uses_depth_texture) { + flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_DEPTH_TEXTURE; + } + + if (p_material->shader_data->uses_normal_texture) { + flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_NORMAL_TEXTURE; + } + + if (ginstance->data->cast_double_sided_shaodows) { + flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_DOUBLE_SIDED_SHADOWS; + } + + if (has_alpha || has_read_screen_alpha || p_material->shader_data->depth_draw == ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == ShaderData::DEPTH_TEST_DISABLED) { + //material is only meant for alpha pass + flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_ALPHA; + if (p_material->shader_data->uses_depth_pre_pass && !(p_material->shader_data->depth_draw == ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == ShaderData::DEPTH_TEST_DISABLED)) { + flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH; + flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_SHADOW; + } + } else { + flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_OPAQUE; + flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH; + flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_SHADOW; + } + + MaterialData *material_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; + } + + GeometryInstanceSurfaceDataCache *sdcache = geometry_instance_surface_alloc.alloc(); + + sdcache->flags = flags; + + sdcache->shader = p_material->shader_data; + sdcache->material_uniform_set = p_material->uniform_set; + sdcache->surface = storage->mesh_get_surface(p_mesh, p_surface); + sdcache->primitive = storage->mesh_surface_get_primitive(sdcache->surface); + sdcache->surface_index = p_surface; + + if (ginstance->data->dirty_dependencies) { + storage->base_update_dependency(p_mesh, &ginstance->data->dependency_tracker); + } + + //shadow + sdcache->shader_shadow = material_shadow->shader_data; + sdcache->material_uniform_set_shadow = material_shadow->uniform_set; + + sdcache->surface_shadow = surface_shadow ? surface_shadow : sdcache->surface; + + sdcache->owner = ginstance; + + sdcache->next = ginstance->surface_caches; + ginstance->surface_caches = sdcache; + + //sortkey + + sdcache->sort.sort_key1 = 0; + sdcache->sort.sort_key2 = 0; + + 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(); //only meshes can repeat anyway + sdcache->sort.uses_forward_gi = ginstance->can_sdfgi; + sdcache->sort.priority = p_material->priority; +} + +void RendererSceneRenderForward::_geometry_instance_add_surface(GeometryInstanceForward *ginstance, uint32_t p_surface, RID p_material, RID p_mesh) { + RID m_src; + + m_src = ginstance->data->material_override.is_valid() ? ginstance->data->material_override : p_material; + + MaterialData *material = nullptr; + + if (m_src.is_valid()) { + material = (MaterialData *)storage->material_get_data(m_src, RendererStorageRD::SHADER_TYPE_3D); + if (!material || !material->shader_data->valid) { + material = nullptr; + } + } + + if (material) { + if (ginstance->data->dirty_dependencies) { + storage->material_update_dependency(m_src, &ginstance->data->dependency_tracker); + } + } else { + material = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D); + m_src = default_material; + } + + ERR_FAIL_COND(!material); + + _geometry_instance_add_surface_with_material(ginstance, p_surface, material, m_src.get_local_index(), storage->material_get_shader_id(m_src), p_mesh); + + while (material->next_pass.is_valid()) { + RID next_pass = material->next_pass; + material = (MaterialData *)storage->material_get_data(next_pass, RendererStorageRD::SHADER_TYPE_3D); + if (!material || !material->shader_data->valid) { + break; + } + if (ginstance->data->dirty_dependencies) { + storage->material_update_dependency(next_pass, &ginstance->data->dependency_tracker); + } + _geometry_instance_add_surface_with_material(ginstance, p_surface, material, next_pass.get_local_index(), storage->material_get_shader_id(next_pass), p_mesh); + } +} + +void RendererSceneRenderForward::_geometry_instance_update(GeometryInstance *p_geometry_instance) { + GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance); + + if (ginstance->data->dirty_dependencies) { + ginstance->data->dependency_tracker.update_begin(); + } + + //add geometry for drawing + switch (ginstance->data->base_type) { + case RS::INSTANCE_MESH: { + const RID *materials = nullptr; + uint32_t surface_count; + RID mesh = ginstance->data->base; + + materials = storage->mesh_get_surface_count_and_materials(mesh, surface_count); + if (materials) { + //if no materials, no surfaces. + const RID *inst_materials = ginstance->data->surface_materials.ptr(); + uint32_t surf_mat_count = ginstance->data->surface_materials.size(); + + for (uint32_t j = 0; j < surface_count; j++) { + RID material = (j < surf_mat_count && inst_materials[j].is_valid()) ? inst_materials[j] : materials[j]; + _geometry_instance_add_surface(ginstance, j, material, mesh); + } + } + + ginstance->instance_count = 1; + + } break; + + case RS::INSTANCE_MULTIMESH: { + RID mesh = storage->multimesh_get_mesh(ginstance->data->base); + if (mesh.is_valid()) { + const RID *materials = nullptr; + uint32_t surface_count; + + materials = storage->mesh_get_surface_count_and_materials(mesh, surface_count); + if (materials) { + for (uint32_t j = 0; j < surface_count; j++) { + _geometry_instance_add_surface(ginstance, j, materials[j], mesh); + } + } + + ginstance->instance_count = storage->multimesh_get_instances_to_draw(ginstance->data->base); + } + + } break; +#if 0 + case RS::INSTANCE_IMMEDIATE: { + RasterizerStorageGLES3::Immediate *immediate = storage->immediate_owner.getornull(inst->base); + ERR_CONTINUE(!immediate); + + _add_geometry(immediate, inst, nullptr, -1, p_depth_pass, p_shadow_pass); + + } break; +#endif + case RS::INSTANCE_PARTICLES: { + int draw_passes = storage->particles_get_draw_passes(ginstance->data->base); + + for (int j = 0; j < draw_passes; j++) { + RID mesh = storage->particles_get_draw_pass_mesh(ginstance->data->base, j); + if (!mesh.is_valid()) + continue; + + const RID *materials = nullptr; + uint32_t surface_count; + + materials = storage->mesh_get_surface_count_and_materials(mesh, surface_count); + if (materials) { + for (uint32_t k = 0; k < surface_count; k++) { + _geometry_instance_add_surface(ginstance, k, materials[k], mesh); + } + } + } + + ginstance->instance_count = storage->particles_get_amount(ginstance->data->base); + + } break; + + default: { + } + } + + //Fill push constant + + bool store_transform = true; + + if (ginstance->data->base_type == RS::INSTANCE_MULTIMESH) { + ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH; + uint32_t stride; + if (storage->multimesh_get_transform_format(ginstance->data->base) == RS::MULTIMESH_TRANSFORM_2D) { + ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D; + stride = 2; + } else { + stride = 3; + } + if (storage->multimesh_uses_colors(ginstance->data->base)) { + ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR; + stride += 1; + } + if (storage->multimesh_uses_custom_data(ginstance->data->base)) { + ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA; + stride += 1; + } + + ginstance->base_flags |= (stride << INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_SHIFT); + ginstance->transforms_uniform_set = storage->multimesh_get_3d_uniform_set(ginstance->data->base, default_shader_rd, TRANSFORMS_UNIFORM_SET); + + } else if (ginstance->data->base_type == RS::INSTANCE_PARTICLES) { + ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH; + uint32_t stride; + if (false) { // 2D particles + ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D; + stride = 2; + } else { + stride = 3; + } + + ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR; + stride += 1; + + ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA; + stride += 1; + + ginstance->base_flags |= (stride << INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_SHIFT); + + if (!storage->particles_is_using_local_coords(ginstance->data->base)) { + store_transform = false; + } + ginstance->transforms_uniform_set = storage->particles_get_instance_buffer_uniform_set(ginstance->data->base, default_shader_rd, TRANSFORMS_UNIFORM_SET); + + } else if (ginstance->data->base_type == RS::INSTANCE_MESH) { + if (storage->skeleton_is_valid(ginstance->data->skeleton)) { + ginstance->base_flags |= INSTANCE_DATA_FLAG_SKELETON; + ginstance->transforms_uniform_set = storage->skeleton_get_3d_uniform_set(ginstance->data->skeleton, default_shader_rd, TRANSFORMS_UNIFORM_SET); + if (ginstance->data->dirty_dependencies) { + storage->skeleton_update_dependency(ginstance->data->skeleton, &ginstance->data->dependency_tracker); + } + } + } + + ginstance->store_transform_cache = store_transform; + ginstance->can_sdfgi = false; + + 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; + } + } + + if (ginstance->data->dirty_dependencies) { + ginstance->data->dependency_tracker.update_end(); + ginstance->data->dirty_dependencies = false; + } + + ginstance->dirty_list_element.remove_from_list(); +} + +void RendererSceneRenderForward::_update_dirty_geometry_instances() { + while (geometry_instance_dirty_list.first()) { + _geometry_instance_update(geometry_instance_dirty_list.first()->self()); + } +} + +void RendererSceneRenderForward::_geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker) { + switch (p_notification) { + case RendererStorage::DEPENDENCY_CHANGED_MATERIAL: + case RendererStorage::DEPENDENCY_CHANGED_MESH: + case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH: + case RendererStorage::DEPENDENCY_CHANGED_SKELETON_DATA: { + static_cast<RendererSceneRenderForward *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata)); + } break; + case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: { + GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_tracker->userdata); + if (ginstance->data->base_type == RS::INSTANCE_MULTIMESH) { + ginstance->instance_count = static_cast<RendererSceneRenderForward *>(singleton)->storage->multimesh_get_instances_to_draw(ginstance->data->base); + } + } break; + default: { + //rest of notifications of no interest + } break; + } +} +void RendererSceneRenderForward::_geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker) { + static_cast<RendererSceneRenderForward *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata)); +} + +RendererSceneRender::GeometryInstance *RendererSceneRenderForward::geometry_instance_create(RID p_base) { + RS::InstanceType type = storage->get_base_type(p_base); + ERR_FAIL_COND_V(!((1 << type) & RS::INSTANCE_GEOMETRY_MASK), nullptr); + + GeometryInstanceForward *ginstance = geometry_instance_alloc.alloc(); + ginstance->data = memnew(GeometryInstanceForward::Data); + + ginstance->data->base = p_base; + ginstance->data->base_type = type; + ginstance->data->dependency_tracker.userdata = ginstance; + ginstance->data->dependency_tracker.changed_callback = _geometry_instance_dependency_changed; + ginstance->data->dependency_tracker.deleted_callback = _geometry_instance_dependency_deleted; + + _geometry_instance_mark_dirty(ginstance); + + return ginstance; +} +void RendererSceneRenderForward::geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) { + GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance); + ERR_FAIL_COND(!ginstance); + ginstance->data->skeleton = p_skeleton; + _geometry_instance_mark_dirty(ginstance); + ginstance->data->dirty_dependencies = true; +} +void RendererSceneRenderForward::geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) { + GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance); + ERR_FAIL_COND(!ginstance); + ginstance->data->material_override = p_override; + _geometry_instance_mark_dirty(ginstance); + ginstance->data->dirty_dependencies = true; +} +void RendererSceneRenderForward::geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials) { + GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance); + ERR_FAIL_COND(!ginstance); + ginstance->data->surface_materials = p_materials; + _geometry_instance_mark_dirty(ginstance); + ginstance->data->dirty_dependencies = true; +} +void RendererSceneRenderForward::geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) { + GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance); + ERR_FAIL_COND(!ginstance); + ginstance->mesh_instance = p_mesh_instance; + _geometry_instance_mark_dirty(ginstance); +} +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); + ginstance->transform = p_transform; + ginstance->mirror = p_transform.basis.determinant() < 0; + ginstance->data->aabb = p_aabb; + ginstance->transformed_aabb = p_transformed_aabb; + + Vector3 model_scale_vec = p_transform.basis.get_scale_abs(); + // handle non uniform scale here + + float max_scale = MAX(model_scale_vec.x, MAX(model_scale_vec.y, model_scale_vec.z)); + float min_scale = MIN(model_scale_vec.x, MIN(model_scale_vec.y, model_scale_vec.z)); + ginstance->non_uniform_scale = max_scale >= 0.0 && (min_scale / max_scale) < 0.9; + + ginstance->lod_model_scale = max_scale; +} +void RendererSceneRenderForward::geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) { + GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance); + ERR_FAIL_COND(!ginstance); + ginstance->lod_bias = p_lod_bias; +} +void RendererSceneRenderForward::geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) { + GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance); + ERR_FAIL_COND(!ginstance); + ginstance->data->use_baked_light = p_enable; + _geometry_instance_mark_dirty(ginstance); +} +void RendererSceneRenderForward::geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) { + GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance); + ERR_FAIL_COND(!ginstance); + ginstance->data->use_dynamic_gi = p_enable; + _geometry_instance_mark_dirty(ginstance); +} +void RendererSceneRenderForward::geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) { + GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance); + ERR_FAIL_COND(!ginstance); + ginstance->lightmap_instance = p_lightmap_instance; + 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) { + GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance); + ERR_FAIL_COND(!ginstance); + if (p_sh9) { + if (ginstance->lightmap_sh == nullptr) { + ginstance->lightmap_sh = geometry_instance_lightmap_sh.alloc(); + } + + copymem(ginstance->lightmap_sh->sh, p_sh9, sizeof(Color) * 9); + } else { + if (ginstance->lightmap_sh != nullptr) { + geometry_instance_lightmap_sh.free(ginstance->lightmap_sh); + ginstance->lightmap_sh = nullptr; + } + } + _geometry_instance_mark_dirty(ginstance); +} +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->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) { + GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance); + ERR_FAIL_COND(!ginstance); + + ginstance->data->cast_double_sided_shaodows = p_enable; + _geometry_instance_mark_dirty(ginstance); +} + +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->layer_mask = p_layer_mask; +} + +void RendererSceneRenderForward::geometry_instance_free(GeometryInstance *p_geometry_instance) { + GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance); + ERR_FAIL_COND(!ginstance); + if (ginstance->lightmap_sh != nullptr) { + geometry_instance_lightmap_sh.free(ginstance->lightmap_sh); + } + GeometryInstanceSurfaceDataCache *surf = ginstance->surface_caches; + while (surf) { + GeometryInstanceSurfaceDataCache *next = surf->next; + geometry_instance_surface_alloc.free(surf); + surf = next; + } + memdelete(ginstance->data); + geometry_instance_alloc.free(ginstance); +} + +uint32_t RendererSceneRenderForward::geometry_instance_get_pair_mask() { + return (1 << RS::INSTANCE_GI_PROBE); +} +void RendererSceneRenderForward::geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) { +} +void RendererSceneRenderForward::geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) { +} +void RendererSceneRenderForward::geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) { +} + +Transform RendererSceneRenderForward::geometry_instance_get_transform(GeometryInstance *p_instance) { + GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_instance); + ERR_FAIL_COND_V(!ginstance, Transform()); + return ginstance->transform; +} +AABB RendererSceneRenderForward::geometry_instance_get_aabb(GeometryInstance *p_instance) { + GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_instance); + ERR_FAIL_COND_V(!ginstance, AABB()); + return ginstance->data->aabb; +} + +void RendererSceneRenderForward::geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count) { + GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance); + ERR_FAIL_COND(!ginstance); + if (p_gi_probe_instance_count > 0) { + ginstance->gi_probes[0] = p_gi_probe_instances[0]; + } else { + ginstance->gi_probes[0] = RID(); + } + + if (p_gi_probe_instance_count > 1) { + ginstance->gi_probes[1] = p_gi_probe_instances[1]; + } else { + ginstance->gi_probes[1] = RID(); + } } RendererSceneRenderForward::RendererSceneRenderForward(RendererStorageRD *p_storage) : @@ -2788,11 +3351,10 @@ RendererSceneRenderForward::RendererSceneRenderForward(RendererStorageRD *p_stor { //lightmaps - scene_state.max_lightmaps = storage->lightmap_array_get_size(); + scene_state.max_lightmaps = low_end ? 2 : MAX_LIGHTMAPS; defines += "\n#define MAX_LIGHTMAP_TEXTURES " + itos(scene_state.max_lightmaps) + "\n"; defines += "\n#define MAX_LIGHTMAPS " + itos(scene_state.max_lightmaps) + "\n"; - scene_state.lightmaps = memnew_arr(LightmapData, scene_state.max_lightmaps); scene_state.lightmap_buffer = RD::get_singleton()->storage_buffer_create(sizeof(LightmapData) * scene_state.max_lightmaps); } { @@ -3005,24 +3567,11 @@ 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.max_instances = render_list.max_elements; - scene_state.instances = memnew_arr(InstanceData, scene_state.max_instances); - scene_state.instance_buffer = RD::get_singleton()->storage_buffer_create(sizeof(InstanceData) * scene_state.max_instances); - } - - scene_state.uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SceneState::UBO)); - { //default material and shader default_shader = storage->shader_create(); @@ -3068,14 +3617,18 @@ RendererSceneRenderForward::RendererSceneRenderForward(RendererStorageRD *p_stor sampler.compare_op = RD::COMPARE_OP_LESS; shadow_sampler = RD::get_singleton()->sampler_create(sampler); } + + render_list_thread_threshold = GLOBAL_GET("rendering/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)) { @@ -3094,12 +3647,16 @@ RendererSceneRenderForward::~RendererSceneRenderForward() { storage->free(default_material); { - RD::get_singleton()->free(scene_state.uniform_buffer); - RD::get_singleton()->free(scene_state.instance_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); - memdelete_arr(scene_state.instances); - memdelete_arr(scene_state.lightmaps); + 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 4b37f4a391..af78c50fda 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_forward.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_forward.h @@ -31,6 +31,7 @@ #ifndef RENDERING_SERVER_SCENE_RENDER_FORWARD_H #define RENDERING_SERVER_SCENE_RENDER_FORWARD_H +#include "core/templates/paged_allocator.h" #include "servers/rendering/renderer_rd/pipeline_cache_rd.h" #include "servers/rendering/renderer_rd/renderer_scene_render_rd.h" #include "servers/rendering/renderer_rd/renderer_storage_rd.h" @@ -46,7 +47,18 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { enum { SDFGI_MAX_CASCADES = 8, - MAX_GI_PROBES = 8 + 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 */ @@ -166,6 +178,8 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { virtual bool is_animated() const; virtual bool casts_shadows() const; virtual Variant get_default_parameter(const StringName &p_parameter) const; + virtual RS::ShaderNativeSourceCode get_native_source_code() const; + ShaderData(); virtual ~ShaderData(); }; @@ -197,14 +211,6 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { return static_cast<RendererSceneRenderForward *>(singleton)->_create_material_func(static_cast<ShaderData *>(p_shader)); } - /* Push Constant */ - - struct PushConstant { - uint32_t index; - uint32_t pad; - float bake_uv2_offset[2]; - }; - /* Framebuffer */ struct RenderBufferDataForward : public RenderBufferData { @@ -216,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; @@ -239,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); @@ -252,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; @@ -261,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); + 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]; @@ -292,16 +343,6 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { INSTANCE_DATA_FLAG_SKELETON = 1 << 19, }; - struct InstanceData { - float transform[16]; - float normal_transform[16]; - uint32_t flags; - uint32_t instance_uniforms_ofs; //instance_offset in instancing/skeleton buffer - uint32_t gi_offset; //GI information when using lightmapping (VCT or lightmap) - uint32_t mask; - float lightmap_uv_scale[4]; - }; - struct SceneState { struct UBO { float projection_matrix[16]; @@ -313,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]; @@ -381,214 +427,340 @@ 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; + LightmapData lightmaps[MAX_LIGHTMAPS]; + RID lightmap_ids[MAX_LIGHTMAPS]; + bool lightmap_has_sh[MAX_LIGHTMAPS]; + uint32_t lightmaps_used = 0; 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; - RID instance_buffer; - InstanceData *instances; - uint32_t max_instances; + RID giprobe_ids[MAX_GI_PROBES]; + uint32_t giprobes_used = 0; bool used_screen_texture = false; bool used_normal_texture = false; bool used_depth_texture = false; bool used_sss = false; - uint32_t current_shader_index = 0; - uint32_t current_material_index = 0; + + 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; - /* Render List */ + static RendererSceneRenderForward *singleton; - struct RenderList { - int max_elements; - - struct Element { - RendererSceneRender::InstanceBase *instance; - MaterialData *material; - union { - struct { - //from least significant to most significant in sort, TODO: should be endian swapped on big endian - uint64_t geometry_index : 20; - uint64_t material_index : 15; - uint64_t shader_index : 12; - uint64_t uses_instancing : 1; - uint64_t uses_forward_gi : 1; - uint64_t uses_lightmap : 1; - uint64_t depth_layer : 4; - uint64_t priority : 8; - }; - - uint64_t sort_key; + double time; + RID default_shader; + RID default_material; + RID overdraw_material_shader; + RID overdraw_material; + RID wireframe_material_shader; + RID wireframe_material; + RID default_shader_rd; + RID default_shader_sdfgi_rd; + + RID default_vec4_xform_buffer; + RID default_vec4_xform_uniform_set; + + 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 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> + _FORCE_INLINE_ void _render_list_template(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element); + + void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element); + + LocalVector<RD::DrawListID> thread_draw_lists; + void _render_list_thread_function(uint32_t p_thread, RenderListParameters *p_params); + void _render_list_with_threads(RenderListParameters *p_params, RID p_framebuffer, RD::InitialAction p_initial_color_action, RD::FinalAction p_final_color_action, RD::InitialAction p_initial_depth_action, RD::FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2(), const Vector<RID> &p_storage_textures = Vector<RID>()); + + uint32_t render_list_thread_threshold = 500; + + 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; + + struct GeometryInstanceData; + struct GeometryInstanceForward; + + struct GeometryInstanceLightmapSH { + Color sh[9]; + }; + + // Cached data for drawing surfaces + struct GeometryInstanceSurfaceDataCache { + enum { + FLAG_PASS_DEPTH = 1, + FLAG_PASS_OPAQUE = 2, + FLAG_PASS_ALPHA = 4, + FLAG_PASS_SHADOW = 8, + FLAG_USES_SHARED_SHADOW_MATERIAL = 128, + FLAG_USES_SUBSURFACE_SCATTERING = 2048, + FLAG_USES_SCREEN_TEXTURE = 4096, + FLAG_USES_DEPTH_TEXTURE = 8192, + FLAG_USES_NORMAL_TEXTURE = 16384, + FLAG_USES_DOUBLE_SIDED_SHADOWS = 32768, + }; + + union { + struct { + 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; + uint64_t sort_key2; }; - uint32_t surface_index; + } sort; + + RS::PrimitiveType primitive = RS::PRIMITIVE_MAX; + uint32_t flags = 0; + uint32_t surface_index = 0; + + void *surface = nullptr; + RID material_uniform_set; + ShaderData *shader = nullptr; + + void *surface_shadow = nullptr; + RID material_uniform_set_shadow; + ShaderData *shader_shadow = nullptr; + + GeometryInstanceSurfaceDataCache *next = nullptr; + GeometryInstanceForward *owner = nullptr; + }; + + struct GeometryInstanceForward : public GeometryInstance { + //used during rendering + bool mirror = false; + bool non_uniform_scale = false; + float lod_bias = 0.0; + float lod_model_scale = 1.0; + AABB transformed_aabb; //needed for LOD + float depth = 0; + 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; + GeometryInstanceSurfaceDataCache *surface_caches = nullptr; + SelfList<GeometryInstanceForward> dirty_list_element; + + struct Data { + //data used less often goes into regular heap + RID base; + RS::InstanceType base_type; + + RID skeleton; + Vector<RID> surface_materials; + RID material_override; + AABB aabb; + + bool use_dynamic_gi = false; + bool use_baked_light = false; + bool cast_double_sided_shaodows = false; + bool mirror = false; + bool dirty_dependencies = false; + + RendererStorage::DependencyTracker dependency_tracker; }; - Element *base_elements; - Element **elements; + Data *data = nullptr; + + GeometryInstanceForward() : + dirty_list_element(this) {} + }; + + static void _geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker); + static void _geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker); - int element_count; - int alpha_element_count; + SelfList<GeometryInstanceForward>::List geometry_instance_dirty_list; + + PagedAllocator<GeometryInstanceForward> geometry_instance_alloc; + PagedAllocator<GeometryInstanceSurfaceDataCache> geometry_instance_surface_alloc; + PagedAllocator<GeometryInstanceLightmapSH> geometry_instance_lightmap_sh; + + void _geometry_instance_add_surface_with_material(GeometryInstanceForward *ginstance, uint32_t p_surface, MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh); + void _geometry_instance_add_surface(GeometryInstanceForward *ginstance, uint32_t p_surface, RID p_material, RID p_mesh); + void _geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance); + void _geometry_instance_update(GeometryInstance *p_geometry_instance); + void _update_dirty_geometry_instances(); + + bool low_end = false; + + /* Render List */ + + struct RenderList { + 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 struct SortByKey { - _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const { - return A->sort_key < B->sort_key; + _FORCE_INLINE_ bool operator()(const GeometryInstanceSurfaceDataCache *A, const GeometryInstanceSurfaceDataCache *B) const { + return (A->sort.sort_key2 == B->sort.sort_key2) ? (A->sort.sort_key1 < B->sort.sort_key1) : (A->sort.sort_key2 < B->sort.sort_key2); } }; - void sort_by_key(bool p_alpha) { - SortArray<Element *, SortByKey> sorter; - if (p_alpha) { - sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count); - } else { - sorter.sort(elements, element_count); - } + void sort_by_key() { + SortArray<GeometryInstanceSurfaceDataCache *, SortByKey> sorter; + 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 { - _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const { - return A->instance->depth < B->instance->depth; + _FORCE_INLINE_ bool operator()(const GeometryInstanceSurfaceDataCache *A, const GeometryInstanceSurfaceDataCache *B) const { + return (A->owner->depth < B->owner->depth); } }; - void sort_by_depth(bool p_alpha) { //used for shadows + void sort_by_depth() { //used for shadows - SortArray<Element *, SortByDepth> sorter; - if (p_alpha) { - sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count); - } else { - sorter.sort(elements, element_count); - } + SortArray<GeometryInstanceSurfaceDataCache *, SortByDepth> sorter; + sorter.sort(elements.ptr(), elements.size()); } struct SortByReverseDepthAndPriority { - _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const { - uint32_t layer_A = uint32_t(A->priority); - uint32_t layer_B = uint32_t(B->priority); - if (layer_A == layer_B) { - return A->instance->depth > B->instance->depth; - } else { - return layer_A < layer_B; - } + _FORCE_INLINE_ bool operator()(const GeometryInstanceSurfaceDataCache *A, const GeometryInstanceSurfaceDataCache *B) const { + return (A->sort.priority == B->sort.priority) ? (A->owner->depth > B->owner->depth) : (A->sort.priority < B->sort.priority); } }; void sort_by_reverse_depth_and_priority(bool p_alpha) { //used for alpha - SortArray<Element *, SortByReverseDepthAndPriority> sorter; - if (p_alpha) { - sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count); - } else { - sorter.sort(elements, element_count); - } + SortArray<GeometryInstanceSurfaceDataCache *, SortByReverseDepthAndPriority> sorter; + sorter.sort(elements.ptr(), elements.size()); } - _FORCE_INLINE_ Element *add_element() { - if (element_count + alpha_element_count >= max_elements) { - return nullptr; - } - elements[element_count] = &base_elements[element_count]; - return elements[element_count++]; - } - - _FORCE_INLINE_ Element *add_alpha_element() { - if (element_count + alpha_element_count >= max_elements) { - return nullptr; - } - int idx = max_elements - alpha_element_count - 1; - elements[idx] = &base_elements[idx]; - alpha_element_count++; - return elements[idx]; + _FORCE_INLINE_ void add_element(GeometryInstanceSurfaceDataCache *p_element) { + elements.push_back(p_element); } - - void init() { - element_count = 0; - alpha_element_count = 0; - elements = memnew_arr(Element *, max_elements); - base_elements = memnew_arr(Element, max_elements); - for (int i = 0; i < max_elements; i++) { - elements[i] = &base_elements[i]; // assign elements - } - } - - RenderList() { - max_elements = 0; - } - - ~RenderList() { - memdelete_arr(elements); - memdelete_arr(base_elements); - } - }; - - RenderList render_list; - - static RendererSceneRenderForward *singleton; - uint64_t render_pass; - double time; - RID default_shader; - RID default_material; - RID overdraw_material_shader; - RID overdraw_material; - RID wireframe_material_shader; - RID wireframe_material; - RID default_shader_rd; - RID default_shader_sdfgi_rd; - - 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_lightmaps(const PagedArray<InstanceBase *> &p_lightmaps, const Transform &p_cam_transform); - - void _fill_instances(RenderList::Element **p_elements, int p_element_count, bool p_for_depth, bool p_has_sdfgi = false, bool p_has_opaque_gi = false); - void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **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); - _FORCE_INLINE_ void _add_geometry(InstanceBase *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi = false); - _FORCE_INLINE_ void _add_geometry_with_material(InstanceBase *p_instance, uint32_t p_surface, MaterialData *p_material, RID p_material_rid, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi = false); + RenderList render_list[RENDER_LIST_MAX]; - void _fill_render_list(const PagedArray<InstanceBase *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_using_sdfgi = false); - - Map<Size2i, RID> sdfgi_framebuffer_size_cache; +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, 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); - bool low_end = false; + 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); -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<InstanceBase *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<InstanceBase *> &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<InstanceBase *> &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_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region); - virtual void _render_uv2(const PagedArray<InstanceBase *> &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<InstanceBase *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture); - virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<InstanceBase *> &p_instances); + 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); + virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances); public: + virtual GeometryInstance *geometry_instance_create(RID p_base); + virtual void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton); + virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override); + virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials); + virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance); + virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb); + virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask); + virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias); + virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable); + virtual void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable); + virtual 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); + virtual void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9); + virtual void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset); + virtual void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable); + + virtual Transform geometry_instance_get_transform(GeometryInstance *p_instance); + virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance); + + virtual void geometry_instance_free(GeometryInstance *p_geometry_instance); + + virtual uint32_t geometry_instance_get_pair_mask(); + virtual void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count); + virtual void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count); + virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count); + virtual void geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count); + virtual void set_time(double p_time, double p_step); virtual bool free(RID p_rid); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 8e55dea2b1..09d2c032a8 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); } } } @@ -1150,150 +1148,71 @@ 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; - } - - 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++; - } + RD::get_singleton()->draw_command_begin_label("SDFGI Update dynamic Light"); - 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; + /* Update dynamic light */ - for (uint32_t j = 0; j < p_positional_light_count; j++) { - if (idx == SDFGI::MAX_DYNAMIC_LIGHTS) { - break; - } - - 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.multibounce = rb->sdfgi->uses_multibounce; + push_constant.y_mult = rb->sdfgi->y_mult; - 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 +1222,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 +1281,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 +1295,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); + } + + //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()->compute_list_add_barrier(compute_list); //wait until done + 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 +1345,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 +1444,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 +1529,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 +1779,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 +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 = 10; - u.ids.push_back(p_reflection_buffer); + u.ids.push_back(rb->reflection_buffer); uniforms.push_back(u); } @@ -1765,12 +1851,26 @@ 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() { @@ -2288,7 +2388,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 +2440,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) { @@ -2674,6 +2774,12 @@ Variant RendererSceneRenderRD::SkyShaderData::get_default_parameter(const String return Variant(); } +RS::ShaderNativeSourceCode RendererSceneRenderRD::SkyShaderData::get_native_source_code() const { + RendererSceneRenderRD *scene_singleton = (RendererSceneRenderRD *)RendererSceneRenderRD::singleton; + + return scene_singleton->sky_shader.shader.version_get_native_source_code(version); +} + RendererSceneRenderRD::SkyShaderData::SkyShaderData() { valid = false; } @@ -3045,7 +3151,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); @@ -3059,8 +3165,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) { @@ -3071,25 +3178,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; @@ -3098,6 +3186,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); @@ -3227,6 +3318,10 @@ RID RendererSceneRenderRD::reflection_atlas_create() { ra.count = GLOBAL_GET("rendering/quality/reflection_atlas/reflection_count"); ra.size = GLOBAL_GET("rendering/quality/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); } @@ -3238,6 +3333,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; @@ -3247,7 +3344,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()) { @@ -3504,13 +3600,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; } @@ -3518,7 +3629,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 @@ -3537,16 +3647,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) { @@ -3801,10 +3902,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; } @@ -3812,21 +3927,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) { @@ -3946,11 +4049,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; @@ -3996,29 +4095,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) { @@ -4035,6 +4111,19 @@ void RendererSceneRenderRD::decal_instance_set_transform(RID p_decal, const Tran ///////////////////////////////// +RID RendererSceneRenderRD::lightmap_instance_create(RID p_lightmap) { + LightmapInstance li; + li.lightmap = p_lightmap; + return lightmap_instance_owner.make_rid(li); +} +void RendererSceneRenderRD::lightmap_instance_set_transform(RID p_lightmap, const Transform &p_transform) { + LightmapInstance *li = lightmap_instance_owner.getornull(p_lightmap); + ERR_FAIL_COND(!li); + li->transform = p_transform; +} + +///////////////////////////////// + RID RendererSceneRenderRD::gi_probe_instance_create(RID p_base) { GIProbeInstance gi_probe; gi_probe.probe = p_base; @@ -4061,7 +4150,7 @@ bool RendererSceneRenderRD::gi_probe_needs_update(RID p_probe) const { return gi_probe->last_probe_version != storage->gi_probe_get_version(gi_probe->probe); } -void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<InstanceBase *> &p_dynamic_objects) { +void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<GeometryInstance *> &p_dynamic_objects) { GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_probe); ERR_FAIL_COND(!gi_probe); @@ -4106,7 +4195,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; @@ -4397,7 +4486,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); @@ -4415,7 +4507,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; @@ -4447,8 +4539,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); @@ -4466,7 +4558,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); } } @@ -4578,13 +4670,10 @@ void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_ins //this could probably be better parallelized in compute.. for (int i = 0; i < (int)p_dynamic_objects.size(); i++) { - InstanceBase *instance = p_dynamic_objects[i]; - //not used, so clear - instance->depth_layer = 0; - instance->depth = 0; + GeometryInstance *instance = p_dynamic_objects[i]; //transform aabb to giprobe - AABB aabb = (to_probe_xform * instance->transform).xform(instance->aabb); + AABB aabb = (to_probe_xform * geometry_instance_get_transform(instance)).xform(geometry_instance_get_aabb(instance)); //this needs to wrap to grid resolution to avoid jitter //also extend margin a bit just in case @@ -4834,7 +4923,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); @@ -4861,7 +4959,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; @@ -5082,9 +5180,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()) { @@ -5125,6 +5220,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) { @@ -5257,9 +5359,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) + " "); } } @@ -5272,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.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) + " "); } } @@ -5287,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_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"); } } @@ -5300,7 +5408,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; @@ -5309,6 +5419,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; @@ -5329,9 +5440,9 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen settings.blur_passes = ssao_blur_passes; settings.fadeout_from = ssao_fadeout_from; settings.fadeout_to = ssao_fadeout_to; - settings.screen_size = Size2i(rb->width, rb->height); + settings.full_screen_size = Size2i(rb->width, rb->height); settings.half_screen_size = Size2i(buffer_width, buffer_height); - settings.quarter_size = Size2i(half_width, half_height); + settings.quarter_screen_size = Size2i(half_width, half_height); storage->get_effects()->generate_ssao(rb->depth_texture, p_normal_buffer, rb->ssao.depth, rb->ssao.depth_slices, rb->ssao.ao_deinterleaved, rb->ssao.ao_deinterleaved_slices, rb->ssao.ao_pong, rb->ssao.ao_pong_slices, rb->ssao.ao_final, rb->ssao.importance_map[0], rb->ssao.importance_map[1], p_projection, settings, uniform_sets_are_invalid); } @@ -5524,10 +5635,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); } } @@ -5683,7 +5794,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); @@ -5719,6 +5830,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); @@ -5856,6 +5978,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); { @@ -5896,6 +6023,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) { @@ -6006,17 +6139,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++; + } + + 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; - RID base_probe = reflection_probe_instance_get_probe(rpi); + rpi->render_index = i; + + RID base_probe = rpi->probe; Cluster::ReflectionData &reflection_ubo = cluster.reflections[i]; @@ -6025,7 +6175,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); @@ -6034,46 +6184,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()); @@ -6083,7 +6237,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; @@ -6119,9 +6273,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; @@ -6200,28 +6354,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: { @@ -6258,170 +6412,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; + + current_cluster_builder->add_light(type == RS::LIGHT_SPOT ? ClusterBuilderRD::LIGHT_TYPE_SPOT : ClusterBuilderRD::LIGHT_TYPE_OMNI, light_transform, radius, spot_angle); - //update UBO for forward rendering, blit to texture for clustered + r_positional_light_count++; } - if (light_count) { - RD::get_singleton()->buffer_update(cluster.light_buffer, 0, sizeof(Cluster::LightData) * light_count, cluster.lights, true); + //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 (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); } } @@ -6430,18 +6615,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); @@ -6449,18 +6642,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(); @@ -6545,19 +6763,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); @@ -6579,49 +6796,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); @@ -6644,6 +6818,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); @@ -6657,11 +6833,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); @@ -6678,162 +6859,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)) { @@ -6845,10 +6870,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); @@ -6858,10 +6884,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); } @@ -6870,23 +6896,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); } @@ -6894,7 +6919,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); } @@ -6954,6 +6979,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); @@ -6999,7 +7038,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(); @@ -7015,51 +7054,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; @@ -7067,93 +7133,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()->compute_list_add_barrier(compute_list); + RD::get_singleton()->draw_command_end_label(); + + RD::get_singleton()->compute_list_end(); + + 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<InstanceBase *> &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<InstanceBase *> &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) { @@ -7161,12 +7346,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); @@ -7177,27 +7476,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<InstanceBase *> &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; @@ -7230,7 +7528,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; @@ -7245,15 +7542,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 @@ -7262,6 +7555,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; @@ -7280,11 +7575,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) { @@ -7293,10 +7585,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; @@ -7307,57 +7606,52 @@ 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); } } -void RendererSceneRenderRD::render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +void RendererSceneRenderRD::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_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<InstanceBase *> &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); @@ -7373,16 +7667,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 @@ -7405,6 +7701,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; @@ -7429,7 +7728,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 @@ -7471,7 +7770,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); @@ -7479,7 +7778,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->uses_multibounce) { + //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 @@ -7488,7 +7804,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(); @@ -7502,7 +7818,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 @@ -7522,7 +7838,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; @@ -7540,7 +7856,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; } @@ -7552,7 +7868,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 @@ -7562,7 +7878,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 { @@ -7572,7 +7888,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); @@ -7589,7 +7905,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; @@ -7607,7 +7923,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; } @@ -7654,14 +7970,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); @@ -7691,10 +8007,11 @@ 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(); } } -void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<InstanceBase *> &p_instances) { +void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<GeometryInstance *> &p_instances) { ERR_FAIL_COND(!storage->particles_collision_is_heightfield(p_collider)); Vector3 extents = storage->particles_collision_get_extents(p_collider) * p_transform.basis.get_scale(); CameraMatrix cm; @@ -7711,32 +8028,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; + RD::get_singleton()->draw_command_begin_label("SDFGI Render Static Lighs"); - 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; - - //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()); @@ -7792,18 +8094,45 @@ 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.multibounce = false; // this is static light, do not multibounce yet + dl_push_constant.y_mult = rb->sdfgi->y_mult; + + //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) { @@ -7814,6 +8143,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) { @@ -7827,6 +8158,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 @@ -7836,6 +8170,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 @@ -7844,6 +8182,8 @@ bool RendererSceneRenderRD::free(RID p_rid) { reflection_probe_instance_owner.free(p_rid); } else if (decal_instance_owner.owns(p_rid)) { decal_instance_owner.free(p_rid); + } else if (lightmap_instance_owner.owns(p_rid)) { + lightmap_instance_owner.free(p_rid); } else if (gi_probe_instance_owner.owns(p_rid)) { GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_rid); if (gi_probe->texture.is_valid()) { @@ -7979,23 +8319,28 @@ TypedArray<Image> RendererSceneRenderRD::bake_render_uv2(RID p_base, const Vecto //RID sampled_light; - InstanceBase ins; + GeometryInstance *gi = geometry_instance_create(p_base); + + uint32_t sc = RSG::storage->mesh_get_surface_count(p_base); + Vector<RID> materials; + materials.resize(sc); - ins.base_type = RSG::storage->get_base_type(p_base); - ins.base = p_base; - ins.materials.resize(RSG::storage->mesh_get_surface_count(p_base)); - for (int i = 0; i < ins.materials.size(); i++) { - if (i < p_material_overrides.size()) { - ins.materials.write[i] = p_material_overrides[i]; + for (uint32_t i = 0; i < sc; i++) { + if (i < (uint32_t)p_material_overrides.size()) { + materials.write[i] = p_material_overrides[i]; } } + geometry_instance_set_surface_materials(gi, materials); + if (cull_argument.size() == 0) { cull_argument.push_back(nullptr); } - cull_argument[0] = &ins; + cull_argument[0] = gi; _render_uv2(cull_argument, fb, Rect2i(0, 0, p_image_size.width, p_image_size.height)); + geometry_instance_free(gi); + TypedArray<Image> ret; { @@ -8047,20 +8392,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; } @@ -8076,13 +8418,21 @@ bool RendererSceneRenderRD::is_low_end() const { } RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) { + max_cluster_elements = GLOBAL_GET("rendering/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; + + sdfgi_ray_count = RS::EnvironmentSDFGIRayCount(CLAMP(int32_t(GLOBAL_GET("rendering/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/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/sdfgi/frames_to_update_lights")), 0, int32_t(RS::ENV_SDFGI_UPDATE_LIGHT_MAX - 1))); + + directional_shadow.size = GLOBAL_GET("rendering/quality/directional_shadow/size"); + directional_shadow.use_16_bits = GLOBAL_GET("rendering/quality/directional_shadow/16_bits"); uint32_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE); @@ -8376,6 +8726,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"); @@ -8410,11 +8763,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++) { @@ -8458,31 +8818,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); @@ -8490,15 +8852,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; @@ -8511,6 +8864,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)); } { @@ -8543,16 +8897,13 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) { 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")); cull_argument.set_page_pool(&cull_argument_pool); + + gi.half_resolution = GLOBAL_GET("rendering/quality/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); } @@ -8576,6 +8927,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); } @@ -8597,15 +8949,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 af35e1b3b4..cdcdb73132 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,17 +104,22 @@ 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<InstanceBase *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<InstanceBase *> &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<InstanceBase *> &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_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; - virtual void _render_uv2(const PagedArray<InstanceBase *> &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<InstanceBase *> &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; - virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<InstanceBase *> &p_instances) = 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; + virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) = 0; virtual void _debug_giprobe(RID p_gi_probe, RenderingDevice::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha); void _debug_sdfgi_probes(RID p_render_buffers, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform); @@ -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,11 +137,19 @@ 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<InstanceBase *> cull_argument_pool; - PagedArray<InstanceBase *> cull_argument; //need this to exist + PagedArrayPool<GeometryInstance *> cull_argument_pool; + PagedArray<GeometryInstance *> cull_argument; //need this to exist private: RS::ViewportDebugDraw debug_draw = RS::VIEWPORT_DEBUG_DRAW_DISABLED; double time_step = 0; @@ -233,6 +244,7 @@ private: virtual bool is_animated() const; virtual bool casts_shadows() const; virtual Variant get_default_parameter(const StringName &p_parameter) const; + virtual RS::ShaderNativeSourceCode get_native_source_code() const; SkyShaderData(); virtual ~SkyShaderData(); }; @@ -340,6 +352,8 @@ private: }; Vector<Reflection> reflections; + + ClusterBuilderRD *cluster_builder = nullptr; }; mutable RID_Owner<ReflectionAtlas> reflection_atlas_owner; @@ -374,6 +388,15 @@ private: mutable RID_Owner<DecalInstance> decal_instance_owner; + /* LIGHTMAP INSTANCE */ + + struct LightmapInstance { + RID lightmap; + Transform transform; + }; + + mutable RID_Owner<LightmapInstance> lightmap_instance_owner; + /* GIPROBE INSTANCE */ struct GIProbeLight { @@ -383,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; @@ -562,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 @@ -593,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 */ @@ -615,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 */ @@ -642,7 +657,7 @@ private: RS::LightType light_type = RS::LIGHT_DIRECTIONAL; - ShadowTransform shadow_transform[4]; + ShadowTransform shadow_transform[6]; AABB aabb; RID self; @@ -721,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 @@ -823,6 +839,9 @@ private: /* RENDER BUFFERS */ + ClusterBuilderSharedDataRD cluster_builder_shared; + ClusterBuilderRD *current_cluster_builder = nullptr; + struct SDFGI; struct VolumetricFog; @@ -848,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; @@ -887,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; @@ -948,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,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; @@ -1105,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]; @@ -1246,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]; @@ -1287,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 }; @@ -1303,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; @@ -1370,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; @@ -1403,6 +1517,8 @@ private: float spread; RID light_density_map; + RID prev_light_density_map; + RID fog_map; RID uniform_set; RID uniform_set2; @@ -1410,6 +1526,8 @@ private: RID sky_uniform_set; int last_shadow_filter = -1; + + Transform prev_cam_transform; }; enum { @@ -1421,7 +1539,7 @@ private: }; struct VolumetricFogShader { - struct PushConstant { + struct ParamsUBO { float fog_frustum_size_begin[2]; float fog_frustum_size_end[2]; @@ -1439,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]; @@ -1453,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); @@ -1470,13 +1597,21 @@ 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; + /* 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) { @@ -1497,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); @@ -1516,7 +1651,6 @@ 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 */ @@ -1573,12 +1707,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); @@ -1592,6 +1724,7 @@ public: 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_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; @@ -1822,10 +1955,25 @@ public: return decal->transform; } + virtual RID lightmap_instance_create(RID p_lightmap); + virtual void lightmap_instance_set_transform(RID p_lightmap, const Transform &p_transform); + _FORCE_INLINE_ bool lightmap_instance_is_valid(RID p_lightmap_instance) { + return lightmap_instance_owner.getornull(p_lightmap_instance) != nullptr; + } + + _FORCE_INLINE_ RID lightmap_instance_get_lightmap(RID p_lightmap_instance) { + LightmapInstance *li = lightmap_instance_owner.getornull(p_lightmap_instance); + return li->lightmap; + } + _FORCE_INLINE_ Transform lightmap_instance_get_transform(RID p_lightmap_instance) { + LightmapInstance *li = lightmap_instance_owner.getornull(p_lightmap_instance); + return li->transform; + } + RID gi_probe_instance_create(RID p_base); void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform); bool gi_probe_needs_update(RID p_probe) const; - void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::InstanceBase *> &p_dynamic_objects); + 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); void gi_probe_set_quality(RS::GIProbeQuality p_quality) { gi_probe_quality = p_quality; } @@ -1875,11 +2023,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; @@ -1900,16 +2051,11 @@ 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<InstanceBase *> &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<InstanceBase *> &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<InstanceBase *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0); - - void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region); + 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_sdfgi(RID p_render_buffers, int p_region, const PagedArray<InstanceBase *> &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_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_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<InstanceBase *> &p_instances); + 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) { scene_pass = p_pass; @@ -1960,10 +2106,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 68983da408..a1358f94fa 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp @@ -873,7 +873,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 +918,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) { @@ -1438,7 +1438,7 @@ void RendererStorageRD::shader_set_code(RID p_shader, const String &p_code) { for (Set<Material *>::Element *E = shader->owners.front(); E; E = E->next()) { Material *material = E->get(); - material->instance_dependency.instance_notify_changed(false, true); + material->dependency.changed_notify(DEPENDENCY_CHANGED_MATERIAL); _material_queue_update(material, true, true); } } @@ -1499,6 +1499,15 @@ void RendererStorageRD::shader_set_data_request_function(ShaderType p_shader_typ shader_data_request_func[p_shader_type] = p_function; } +RS::ShaderNativeSourceCode RendererStorageRD::shader_get_native_source_code(RID p_shader) const { + Shader *shader = shader_owner.getornull(p_shader); + ERR_FAIL_COND_V(!shader, RS::ShaderNativeSourceCode()); + if (shader->data) { + return shader->data->get_native_source_code(); + } + return RS::ShaderNativeSourceCode(); +} + /* COMMON MATERIAL API */ RID RendererStorageRD::material_create() { @@ -1547,7 +1556,8 @@ void RendererStorageRD::material_set_shader(RID p_material, RID p_shader) { } if (p_shader.is_null()) { - material->instance_dependency.instance_notify_changed(false, true); + material->dependency.changed_notify(DEPENDENCY_CHANGED_MATERIAL); + material->shader_id = 0; return; } @@ -1555,6 +1565,7 @@ void RendererStorageRD::material_set_shader(RID p_material, RID p_shader) { ERR_FAIL_COND(!shader); material->shader = shader; material->shader_type = shader->type; + material->shader_id = p_shader.get_local_index(); shader->owners.insert(material); if (shader->type == SHADER_TYPE_MAX) { @@ -1568,7 +1579,7 @@ void RendererStorageRD::material_set_shader(RID p_material, RID p_shader) { material->data->set_next_pass(material->next_pass); material->data->set_render_priority(material->priority); //updating happens later - material->instance_dependency.instance_notify_changed(false, true); + material->dependency.changed_notify(DEPENDENCY_CHANGED_MATERIAL); _material_queue_update(material, true, true); } @@ -1613,7 +1624,7 @@ void RendererStorageRD::material_set_next_pass(RID p_material, RID p_next_materi material->data->set_next_pass(p_next_material); } - material->instance_dependency.instance_notify_changed(false, true); + material->dependency.changed_notify(DEPENDENCY_CHANGED_MATERIAL); } void RendererStorageRD::material_set_render_priority(RID p_material, int priority) { @@ -1663,10 +1674,10 @@ void RendererStorageRD::material_get_instance_shader_parameters(RID p_material, } } -void RendererStorageRD::material_update_dependency(RID p_material, InstanceBaseDependency *p_instance) { +void RendererStorageRD::material_update_dependency(RID p_material, DependencyTracker *p_instance) { Material *material = material_owner.getornull(p_material); ERR_FAIL_COND(!material); - p_instance->update_dependency(&material->instance_dependency); + p_instance->update_dependency(&material->dependency); if (material->next_pass.is_valid()) { material_update_dependency(material->next_pass, p_instance); } @@ -2596,7 +2607,13 @@ void RendererStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_su _mesh_instance_add_surface(mi, mesh, mesh->surface_count - 1); } - mesh->instance_dependency.instance_notify_changed(true, true); + 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(); } @@ -2638,7 +2655,7 @@ void RendererStorageRD::mesh_surface_set_material(RID p_mesh, int p_surface, RID ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count); mesh->surfaces[p_surface]->material = p_material; - mesh->instance_dependency.instance_notify_changed(false, true); + mesh->dependency.changed_notify(DEPENDENCY_CHANGED_MATERIAL); mesh->material_cache.clear(); } @@ -2813,6 +2830,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); @@ -2858,8 +2894,14 @@ void RendererStorageRD::mesh_clear(RID p_mesh) { MeshInstance *mi = E->get(); _mesh_instance_clear(mi); } - mesh->instance_dependency.instance_notify_changed(true, true); 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) { @@ -3002,7 +3044,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; @@ -3056,7 +3098,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; @@ -3298,6 +3340,8 @@ void RendererStorageRD::multimesh_allocate(RID p_multimesh, int p_instances, RS: if (multimesh->instances) { multimesh->buffer = RD::get_singleton()->storage_buffer_create(multimesh->instances * multimesh->stride_cache * 4); } + + multimesh->dependency.changed_notify(DEPENDENCY_CHANGED_MULTIMESH); } int RendererStorageRD::multimesh_get_instance_count(RID p_multimesh) const { @@ -3331,7 +3375,7 @@ void RendererStorageRD::multimesh_set_mesh(RID p_multimesh, RID p_mesh) { } } - multimesh->instance_dependency.instance_notify_changed(true, true); + multimesh->dependency.changed_notify(DEPENDENCY_CHANGED_MESH); } #define MULTIMESH_DIRTY_REGION_SIZE 512 @@ -3668,7 +3712,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; } @@ -3690,7 +3734,7 @@ void RendererStorageRD::multimesh_set_buffer(RID p_multimesh, const Vector<float const float *data = p_buffer.ptr(); _multimesh_re_create_aabb(multimesh, data, multimesh->instances); - multimesh->instance_dependency.instance_notify_changed(true, false); + multimesh->dependency.changed_notify(DEPENDENCY_CHANGED_AABB); } } @@ -3731,6 +3775,8 @@ void RendererStorageRD::multimesh_set_visible_instances(RID p_multimesh, int p_v } multimesh->visible_instances = p_visible; + + multimesh->dependency.changed_notify(DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES); } int RendererStorageRD::multimesh_get_visible_instances(RID p_multimesh) const { @@ -3765,14 +3811,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]); } } } @@ -3788,7 +3834,7 @@ void RendererStorageRD::_update_dirty_multimeshes() { //aabb is dirty.. _multimesh_re_create_aabb(multimesh, data, visible_instances); multimesh->aabb_dirty = false; - multimesh->instance_dependency.instance_notify_changed(true, false); + multimesh->dependency.changed_notify(DEPENDENCY_CHANGED_AABB); } } @@ -3926,7 +3972,7 @@ void RendererStorageRD::particles_set_custom_aabb(RID p_particles, const AABB &p Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); particles->custom_aabb = p_aabb; - particles->instance_dependency.instance_notify_changed(true, false); + particles->dependency.changed_notify(DEPENDENCY_CHANGED_AABB); } void RendererStorageRD::particles_set_speed_scale(RID p_particles, float p_scale) { @@ -4155,24 +4201,18 @@ RID RendererStorageRD::particles_get_draw_pass_mesh(RID p_particles, int p_pass) return particles->draw_passes[p_pass]; } -void RendererStorageRD::particles_add_collision(RID p_particles, InstanceBaseDependency *p_instance) { - RendererSceneRender::InstanceBase *instance = static_cast<RendererSceneRender::InstanceBase *>(p_instance); - +void RendererStorageRD::particles_add_collision(RID p_particles, RID p_particles_collision_instance) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); - ERR_FAIL_COND(instance->base_type != RS::INSTANCE_PARTICLES_COLLISION); - - particles->collisions.insert(instance); + particles->collisions.insert(p_particles_collision_instance); } -void RendererStorageRD::particles_remove_collision(RID p_particles, InstanceBaseDependency *p_instance) { - RendererSceneRender::InstanceBase *instance = static_cast<RendererSceneRender::InstanceBase *>(p_instance); - +void RendererStorageRD::particles_remove_collision(RID p_particles, RID p_particles_collision_instance) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); - particles->collisions.erase(instance); + particles->collisions.erase(p_particles_collision_instance); } void RendererStorageRD::_particles_process(Particles *p_particles, float p_delta) { @@ -4272,9 +4312,15 @@ void RendererStorageRD::_particles_process(Particles *p_particles, float p_delta to_particles = p_particles->emission_transform.affine_inverse(); } uint32_t collision_3d_textures_used = 0; - for (const Set<RendererSceneRender::InstanceBase *>::Element *E = p_particles->collisions.front(); E; E = E->next()) { - ParticlesCollision *pc = particles_collision_owner.getornull(E->get()->base); - Transform to_collider = E->get()->transform; + for (const Set<RID>::Element *E = p_particles->collisions.front(); E; E = E->next()) { + ParticlesCollisionInstance *pci = particles_collision_instance_owner.getornull(E->get()); + if (!pci || !pci->active) { + continue; + } + ParticlesCollision *pc = particles_collision_owner.getornull(pci->collision); + ERR_CONTINUE(!pc); + + Transform to_collider = pci->transform; if (p_particles->use_local_coords) { to_collider = to_particles * to_collider; } @@ -4463,7 +4509,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) { @@ -4481,13 +4527,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) { @@ -4509,7 +4555,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(); } @@ -4563,7 +4609,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(); @@ -4575,7 +4621,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(); } @@ -4682,12 +4728,12 @@ 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(); } - particles->instance_dependency.instance_notify_changed(true, false); //make sure shadows are updated + particles->dependency.changed_notify(DEPENDENCY_CHANGED_AABB); } } @@ -4817,6 +4863,10 @@ Variant RendererStorageRD::ParticlesShaderData::get_default_parameter(const Stri return Variant(); } +RS::ShaderNativeSourceCode RendererStorageRD::ParticlesShaderData::get_native_source_code() const { + return base_singleton->particles_shader.shader.version_get_native_source_code(version); +} + RendererStorageRD::ParticlesShaderData::ParticlesShaderData() { valid = false; } @@ -4986,7 +5036,7 @@ void RendererStorageRD::particles_collision_set_collision_type(RID p_particles_c particles_collision->heightfield_texture = RID(); } particles_collision->type = p_type; - particles_collision->instance_dependency.instance_notify_changed(true, false); + particles_collision->dependency.changed_notify(DEPENDENCY_CHANGED_AABB); } void RendererStorageRD::particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) { @@ -5000,7 +5050,7 @@ void RendererStorageRD::particles_collision_set_sphere_radius(RID p_particles_co ERR_FAIL_COND(!particles_collision); particles_collision->radius = p_radius; - particles_collision->instance_dependency.instance_notify_changed(true, false); + particles_collision->dependency.changed_notify(DEPENDENCY_CHANGED_AABB); } void RendererStorageRD::particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) { @@ -5008,7 +5058,7 @@ void RendererStorageRD::particles_collision_set_box_extents(RID p_particles_coll ERR_FAIL_COND(!particles_collision); particles_collision->extents = p_extents; - particles_collision->instance_dependency.instance_notify_changed(true, false); + particles_collision->dependency.changed_notify(DEPENDENCY_CHANGED_AABB); } void RendererStorageRD::particles_collision_set_attractor_strength(RID p_particles_collision, float p_strength) { @@ -5042,7 +5092,7 @@ void RendererStorageRD::particles_collision_set_field_texture(RID p_particles_co void RendererStorageRD::particles_collision_height_field_update(RID p_particles_collision) { ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); ERR_FAIL_COND(!particles_collision); - particles_collision->instance_dependency.instance_notify_changed(true, false); + particles_collision->dependency.changed_notify(DEPENDENCY_CHANGED_AABB); } void RendererStorageRD::particles_collision_set_height_field_resolution(RID p_particles_collision, RS::ParticlesCollisionHeightfieldResolution p_resolution) { @@ -5096,6 +5146,22 @@ bool RendererStorageRD::particles_collision_is_heightfield(RID p_particles_colli return particles_collision->type == RS::PARTICLES_COLLISION_TYPE_HEIGHTFIELD_COLLIDE; } +RID RendererStorageRD::particles_collision_instance_create(RID p_collision) { + ParticlesCollisionInstance pci; + pci.collision = p_collision; + return particles_collision_instance_owner.make_rid(pci); +} +void RendererStorageRD::particles_collision_instance_set_transform(RID p_collision_instance, const Transform &p_transform) { + ParticlesCollisionInstance *pci = particles_collision_instance_owner.getornull(p_collision_instance); + ERR_FAIL_COND(!pci); + pci->transform = p_transform; +} +void RendererStorageRD::particles_collision_instance_set_active(RID p_collision_instance, bool p_active) { + ParticlesCollisionInstance *pci = particles_collision_instance_owner.getornull(p_collision_instance); + ERR_FAIL_COND(!pci); + pci->active = p_active; +} + /* SKELETON API */ RID RendererStorageRD::skeleton_create() { @@ -5149,6 +5215,8 @@ void RendererStorageRD::skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d skeleton->uniform_set_mi = RD::get_singleton()->uniform_set_create(uniforms, skeleton_shader.version_shader[0], SkeletonShader::UNIFORM_SET_SKELETON); } } + + skeleton->dependency.changed_notify(DEPENDENCY_CHANGED_SKELETON_DATA); } int RendererStorageRD::skeleton_get_bone_count(RID p_skeleton) const { @@ -5264,12 +5332,13 @@ 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; - skeleton->instance_dependency.instance_notify_changed(true, false); + skeleton->dependency.changed_notify(DEPENDENCY_CHANGED_SKELETON_BONES); + skeleton->version++; skeleton->dirty = false; @@ -5290,17 +5359,20 @@ RID RendererStorageRD::light_create(RS::LightType p_type) { light.param[RS::LIGHT_PARAM_SPECULAR] = 0.5; light.param[RS::LIGHT_PARAM_RANGE] = 1.0; light.param[RS::LIGHT_PARAM_SIZE] = 0.0; + light.param[RS::LIGHT_PARAM_ATTENUATION] = 1.0; light.param[RS::LIGHT_PARAM_SPOT_ANGLE] = 45; + light.param[RS::LIGHT_PARAM_SPOT_ATTENUATION] = 1.0; light.param[RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE] = 0; light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET] = 0.1; light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET] = 0.3; light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET] = 0.6; light.param[RS::LIGHT_PARAM_SHADOW_FADE_START] = 0.8; - light.param[RS::LIGHT_PARAM_SHADOW_BIAS] = 0.02; light.param[RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] = 1.0; + 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] = 0.1; light.param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] = 0.05; - light.param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE] = 1.0; return light_owner.make_rid(light); } @@ -5328,7 +5400,7 @@ void RendererStorageRD::light_set_param(RID p_light, RS::LightParam p_param, flo case RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE: case RS::LIGHT_PARAM_SHADOW_BIAS: { light->version++; - light->instance_dependency.instance_notify_changed(true, false); + light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT); } break; default: { } @@ -5343,7 +5415,7 @@ void RendererStorageRD::light_set_shadow(RID p_light, bool p_enabled) { light->shadow = p_enabled; light->version++; - light->instance_dependency.instance_notify_changed(true, false); + light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT); } void RendererStorageRD::light_set_shadow_color(RID p_light, const Color &p_color) { @@ -5385,7 +5457,7 @@ void RendererStorageRD::light_set_cull_mask(RID p_light, uint32_t p_mask) { light->cull_mask = p_mask; light->version++; - light->instance_dependency.instance_notify_changed(true, false); + light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT); } void RendererStorageRD::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) { @@ -5395,7 +5467,7 @@ void RendererStorageRD::light_set_reverse_cull_face_mode(RID p_light, bool p_ena light->reverse_cull = p_enabled; light->version++; - light->instance_dependency.instance_notify_changed(true, false); + light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT); } void RendererStorageRD::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) { @@ -5405,7 +5477,7 @@ void RendererStorageRD::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bak light->bake_mode = p_bake_mode; light->version++; - light->instance_dependency.instance_notify_changed(true, false); + light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT); } void RendererStorageRD::light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) { @@ -5415,7 +5487,7 @@ void RendererStorageRD::light_set_max_sdfgi_cascade(RID p_light, uint32_t p_casc light->max_sdfgi_cascade = p_cascade; light->version++; - light->instance_dependency.instance_notify_changed(true, false); + light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT); } void RendererStorageRD::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) { @@ -5425,7 +5497,7 @@ void RendererStorageRD::light_omni_set_shadow_mode(RID p_light, RS::LightOmniSha light->omni_shadow_mode = p_mode; light->version++; - light->instance_dependency.instance_notify_changed(true, false); + light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT); } RS::LightOmniShadowMode RendererStorageRD::light_omni_get_shadow_mode(RID p_light) { @@ -5441,7 +5513,7 @@ void RendererStorageRD::light_directional_set_shadow_mode(RID p_light, RS::Light light->directional_shadow_mode = p_mode; light->version++; - light->instance_dependency.instance_notify_changed(true, false); + light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT); } void RendererStorageRD::light_directional_set_blend_splits(RID p_light, bool p_enable) { @@ -5450,7 +5522,7 @@ void RendererStorageRD::light_directional_set_blend_splits(RID p_light, bool p_e light->directional_blend_splits = p_enable; light->version++; - light->instance_dependency.instance_notify_changed(true, false); + light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT); } bool RendererStorageRD::light_directional_get_blend_splits(RID p_light) const { @@ -5549,7 +5621,7 @@ void RendererStorageRD::reflection_probe_set_update_mode(RID p_probe, RS::Reflec ERR_FAIL_COND(!reflection_probe); reflection_probe->update_mode = p_mode; - reflection_probe->instance_dependency.instance_notify_changed(true, false); + reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE); } void RendererStorageRD::reflection_probe_set_intensity(RID p_probe, float p_intensity) { @@ -5586,7 +5658,7 @@ void RendererStorageRD::reflection_probe_set_max_distance(RID p_probe, float p_d reflection_probe->max_distance = p_distance; - reflection_probe->instance_dependency.instance_notify_changed(true, false); + reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE); } void RendererStorageRD::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) { @@ -5597,7 +5669,7 @@ void RendererStorageRD::reflection_probe_set_extents(RID p_probe, const Vector3 return; } reflection_probe->extents = p_extents; - reflection_probe->instance_dependency.instance_notify_changed(true, false); + reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE); } void RendererStorageRD::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) { @@ -5605,7 +5677,7 @@ void RendererStorageRD::reflection_probe_set_origin_offset(RID p_probe, const Ve ERR_FAIL_COND(!reflection_probe); reflection_probe->origin_offset = p_offset; - reflection_probe->instance_dependency.instance_notify_changed(true, false); + reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE); } void RendererStorageRD::reflection_probe_set_as_interior(RID p_probe, bool p_enable) { @@ -5613,7 +5685,7 @@ void RendererStorageRD::reflection_probe_set_as_interior(RID p_probe, bool p_ena ERR_FAIL_COND(!reflection_probe); reflection_probe->interior = p_enable; - reflection_probe->instance_dependency.instance_notify_changed(true, false); + reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE); } void RendererStorageRD::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) { @@ -5628,7 +5700,7 @@ void RendererStorageRD::reflection_probe_set_enable_shadows(RID p_probe, bool p_ ERR_FAIL_COND(!reflection_probe); reflection_probe->enable_shadows = p_enable; - reflection_probe->instance_dependency.instance_notify_changed(true, false); + reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE); } void RendererStorageRD::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) { @@ -5636,7 +5708,7 @@ void RendererStorageRD::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_l ERR_FAIL_COND(!reflection_probe); reflection_probe->cull_mask = p_layers; - reflection_probe->instance_dependency.instance_notify_changed(true, false); + reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE); } void RendererStorageRD::reflection_probe_set_resolution(RID p_probe, int p_resolution) { @@ -5653,7 +5725,7 @@ void RendererStorageRD::reflection_probe_set_lod_threshold(RID p_probe, float p_ reflection_probe->lod_threshold = p_ratio; - reflection_probe->instance_dependency.instance_notify_changed(true, false); + reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE); } AABB RendererStorageRD::reflection_probe_get_aabb(RID p_probe) const { @@ -5771,7 +5843,7 @@ void RendererStorageRD::decal_set_extents(RID p_decal, const Vector3 &p_extents) Decal *decal = decal_owner.getornull(p_decal); ERR_FAIL_COND(!decal); decal->extents = p_extents; - decal->instance_dependency.instance_notify_changed(true, false); + decal->dependency.changed_notify(DEPENDENCY_CHANGED_AABB); } void RendererStorageRD::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) { @@ -5795,7 +5867,7 @@ void RendererStorageRD::decal_set_texture(RID p_decal, RS::DecalTexture p_type, texture_add_to_decal_atlas(decal->textures[p_type]); } - decal->instance_dependency.instance_notify_changed(false, true); + decal->dependency.changed_notify(DEPENDENCY_CHANGED_DECAL); } void RendererStorageRD::decal_set_emission_energy(RID p_decal, float p_energy) { @@ -5820,7 +5892,7 @@ void RendererStorageRD::decal_set_cull_mask(RID p_decal, uint32_t p_layers) { Decal *decal = decal_owner.getornull(p_decal); ERR_FAIL_COND(!decal); decal->cull_mask = p_layers; - decal->instance_dependency.instance_notify_changed(true, false); + decal->dependency.changed_notify(DEPENDENCY_CHANGED_AABB); } void RendererStorageRD::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) { @@ -5977,7 +6049,7 @@ void RendererStorageRD::gi_probe_allocate(RID p_gi_probe, const Transform &p_to_ gi_probe->version++; gi_probe->data_version++; - gi_probe->instance_dependency.instance_notify_changed(true, false); + gi_probe->dependency.changed_notify(DEPENDENCY_CHANGED_AABB); } AABB RendererStorageRD::gi_probe_get_bounds(RID p_gi_probe) const { @@ -6908,7 +6980,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 */ @@ -6924,7 +6996,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); @@ -6935,7 +7007,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(); } @@ -7055,45 +7127,45 @@ void RendererStorageRD::render_target_set_backbuffer_uniform_set(RID p_render_ta rt->backbuffer_uniform_set = p_uniform_set; } -void RendererStorageRD::base_update_dependency(RID p_base, InstanceBaseDependency *p_instance) { +void RendererStorageRD::base_update_dependency(RID p_base, DependencyTracker *p_instance) { if (mesh_owner.owns(p_base)) { Mesh *mesh = mesh_owner.getornull(p_base); - p_instance->update_dependency(&mesh->instance_dependency); + p_instance->update_dependency(&mesh->dependency); } else if (multimesh_owner.owns(p_base)) { MultiMesh *multimesh = multimesh_owner.getornull(p_base); - p_instance->update_dependency(&multimesh->instance_dependency); + p_instance->update_dependency(&multimesh->dependency); if (multimesh->mesh.is_valid()) { base_update_dependency(multimesh->mesh, p_instance); } } else if (reflection_probe_owner.owns(p_base)) { ReflectionProbe *rp = reflection_probe_owner.getornull(p_base); - p_instance->update_dependency(&rp->instance_dependency); + p_instance->update_dependency(&rp->dependency); } else if (decal_owner.owns(p_base)) { Decal *decal = decal_owner.getornull(p_base); - p_instance->update_dependency(&decal->instance_dependency); + p_instance->update_dependency(&decal->dependency); } else if (gi_probe_owner.owns(p_base)) { GIProbe *gip = gi_probe_owner.getornull(p_base); - p_instance->update_dependency(&gip->instance_dependency); + p_instance->update_dependency(&gip->dependency); } else if (lightmap_owner.owns(p_base)) { Lightmap *lm = lightmap_owner.getornull(p_base); - p_instance->update_dependency(&lm->instance_dependency); + p_instance->update_dependency(&lm->dependency); } else if (light_owner.owns(p_base)) { Light *l = light_owner.getornull(p_base); - p_instance->update_dependency(&l->instance_dependency); + p_instance->update_dependency(&l->dependency); } else if (particles_owner.owns(p_base)) { Particles *p = particles_owner.getornull(p_base); - p_instance->update_dependency(&p->instance_dependency); + p_instance->update_dependency(&p->dependency); } else if (particles_collision_owner.owns(p_base)) { ParticlesCollision *pc = particles_collision_owner.getornull(p_base); - p_instance->update_dependency(&pc->instance_dependency); + p_instance->update_dependency(&pc->dependency); } } -void RendererStorageRD::skeleton_update_dependency(RID p_skeleton, InstanceBaseDependency *p_instance) { +void RendererStorageRD::skeleton_update_dependency(RID p_skeleton, DependencyTracker *p_instance) { Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND(!skeleton); - p_instance->update_dependency(&skeleton->instance_dependency); + p_instance->update_dependency(&skeleton->dependency); } RS::InstanceType RendererStorageRD::get_base_type(RID p_rid) const { @@ -7299,6 +7371,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 @@ -7353,7 +7426,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); } } } @@ -8114,21 +8187,31 @@ bool RendererStorageRD::free(RID p_rid) { _update_queued_materials(); } material_set_shader(p_rid, RID()); //clean up shader - material->instance_dependency.instance_notify_deleted(p_rid); + material->dependency.deleted_notify(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->instance_dependency.instance_notify_deleted(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); @@ -8136,17 +8219,17 @@ bool RendererStorageRD::free(RID p_rid) { _update_dirty_multimeshes(); multimesh_allocate(p_rid, 0, RS::MULTIMESH_TRANSFORM_2D); MultiMesh *multimesh = multimesh_owner.getornull(p_rid); - multimesh->instance_dependency.instance_notify_deleted(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 *skeleton = skeleton_owner.getornull(p_rid); - skeleton->instance_dependency.instance_notify_deleted(p_rid); + skeleton->dependency.deleted_notify(p_rid); skeleton_owner.free(p_rid); } else if (reflection_probe_owner.owns(p_rid)) { ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_rid); - reflection_probe->instance_dependency.instance_notify_deleted(p_rid); + reflection_probe->dependency.deleted_notify(p_rid); reflection_probe_owner.free(p_rid); } else if (decal_owner.owns(p_rid)) { Decal *decal = decal_owner.getornull(p_rid); @@ -8155,30 +8238,30 @@ bool RendererStorageRD::free(RID p_rid) { texture_remove_from_decal_atlas(decal->textures[i]); } } - decal->instance_dependency.instance_notify_deleted(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 GIProbe *gi_probe = gi_probe_owner.getornull(p_rid); - gi_probe->instance_dependency.instance_notify_deleted(p_rid); + gi_probe->dependency.deleted_notify(p_rid); gi_probe_owner.free(p_rid); } else if (lightmap_owner.owns(p_rid)) { lightmap_set_textures(p_rid, RID(), false); Lightmap *lightmap = lightmap_owner.getornull(p_rid); - lightmap->instance_dependency.instance_notify_deleted(p_rid); + lightmap->dependency.deleted_notify(p_rid); lightmap_owner.free(p_rid); } else if (light_owner.owns(p_rid)) { light_set_projector(p_rid, RID()); //clear projector // delete the texture Light *light = light_owner.getornull(p_rid); - light->instance_dependency.instance_notify_deleted(p_rid); + light->dependency.deleted_notify(p_rid); light_owner.free(p_rid); } else if (particles_owner.owns(p_rid)) { Particles *particles = particles_owner.getornull(p_rid); _particles_free_data(particles); - particles->instance_dependency.instance_notify_deleted(p_rid); + particles->dependency.deleted_notify(p_rid); particles_owner.free(p_rid); } else if (particles_collision_owner.owns(p_rid)) { ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_rid); @@ -8186,8 +8269,10 @@ bool RendererStorageRD::free(RID p_rid) { if (particles_collision->heightfield_texture.is_valid()) { RD::get_singleton()->free(particles_collision->heightfield_texture); } - particles_collision->instance_dependency.instance_notify_deleted(p_rid); + particles_collision->dependency.deleted_notify(p_rid); particles_collision_owner.free(p_rid); + } else if (particles_collision_instance_owner.owns(p_rid)) { + particles_collision_instance_owner.free(p_rid); } else if (render_target_owner.owns(p_rid)) { RenderTarget *rt = render_target_owner.getornull(p_rid); @@ -8212,11 +8297,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 { @@ -8736,7 +8821,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"; diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h index 6d1587185e..48d43568c4 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++) { @@ -127,6 +142,8 @@ public: virtual bool is_animated() const = 0; virtual bool casts_shadows() const = 0; virtual Variant get_default_parameter(const StringName &p_parameter) const = 0; + virtual RS::ShaderNativeSourceCode get_native_source_code() const { return RS::ShaderNativeSourceCode(); } + virtual ~ShaderData() {} }; @@ -360,6 +377,7 @@ private: Shader *shader; //shortcut to shader data and type ShaderType shader_type; + uint32_t shader_id = 0; bool update_requested; bool uniform_dirty; bool texture_dirty; @@ -367,7 +385,7 @@ private: Map<StringName, Variant> params; int32_t priority; RID next_pass; - RendererStorage::InstanceDependency instance_dependency; + Dependency dependency; }; MaterialDataRequestFunction material_data_request_func[SHADER_TYPE_MAX]; @@ -460,7 +478,10 @@ private: List<MeshInstance *> instances; - RendererStorage::InstanceDependency instance_dependency; + RID shadow_mesh; + Set<Mesh *> shadow_owners; + + Dependency dependency; }; mutable RID_Owner<Mesh> mesh_owner; @@ -563,7 +584,7 @@ private: bool dirty = false; MultiMesh *dirty_list = nullptr; - RendererStorage::InstanceDependency instance_dependency; + Dependency dependency; }; mutable RID_Owner<MultiMesh> multimesh_owner; @@ -734,7 +755,7 @@ private: ParticleEmissionBuffer *emission_buffer = nullptr; RID emission_storage_buffer; - Set<RendererSceneRender::InstanceBase *> collisions; + Set<RID> collisions; Particles() : inactive(true), @@ -761,7 +782,7 @@ private: clear(true) { } - RendererStorage::InstanceDependency instance_dependency; + Dependency dependency; ParticlesFrameParams frame_params; }; @@ -839,6 +860,8 @@ private: virtual bool is_animated() const; virtual bool casts_shadows() const; virtual Variant get_default_parameter(const StringName &p_parameter) const; + virtual RS::ShaderNativeSourceCode get_native_source_code() const; + ParticlesShaderData(); virtual ~ParticlesShaderData(); }; @@ -889,11 +912,19 @@ private: RS::ParticlesCollisionHeightfieldResolution heightfield_resolution = RS::PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_1024; - RendererStorage::InstanceDependency instance_dependency; + Dependency dependency; }; mutable RID_Owner<ParticlesCollision> particles_collision_owner; + struct ParticlesCollisionInstance { + RID collision; + Transform transform; + bool active = false; + }; + + mutable RID_Owner<ParticlesCollisionInstance> particles_collision_instance_owner; + /* Skeleton */ struct Skeleton { @@ -911,7 +942,7 @@ private: uint64_t version = 1; - RendererStorage::InstanceDependency instance_dependency; + Dependency dependency; }; mutable RID_Owner<Skeleton> skeleton_owner; @@ -943,7 +974,7 @@ private: bool directional_sky_only = false; uint64_t version = 0; - RendererStorage::InstanceDependency instance_dependency; + Dependency dependency; }; mutable RID_Owner<Light> light_owner; @@ -966,7 +997,7 @@ private: uint32_t cull_mask = (1 << 20) - 1; float lod_threshold = 0.01; - RendererStorage::InstanceDependency instance_dependency; + Dependency dependency; }; mutable RID_Owner<ReflectionProbe> reflection_probe_owner; @@ -987,7 +1018,7 @@ private: float distance_fade_length = 1; float normal_fade = 0.0; - RendererStorage::InstanceDependency instance_dependency; + Dependency dependency; }; mutable RID_Owner<Decal> decal_owner; @@ -1025,7 +1056,7 @@ private: uint32_t version = 1; uint32_t data_version = 1; - RendererStorage::InstanceDependency instance_dependency; + Dependency dependency; }; GiprobeSdfShaderRD giprobe_sdf_shader; @@ -1054,7 +1085,7 @@ private: int32_t over = EMPTY_LEAF, under = EMPTY_LEAF; }; - RendererStorage::InstanceDependency instance_dependency; + Dependency dependency; }; bool using_lightmap_array; //high end uses this @@ -1330,6 +1361,8 @@ public: Variant shader_get_param_default(RID p_shader, const StringName &p_param) const; void shader_set_data_request_function(ShaderType p_shader_type, ShaderDataRequestFunction p_function); + virtual RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const; + /* COMMON MATERIAL API */ RID material_create(); @@ -1347,11 +1380,16 @@ public: void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters); - void material_update_dependency(RID p_material, InstanceBaseDependency *p_instance); + void material_update_dependency(RID p_material, DependencyTracker *p_instance); void material_force_update_textures(RID p_material, ShaderType p_shader_type); void material_set_data_request_function(ShaderType p_shader_type, MaterialDataRequestFunction p_function); + _FORCE_INLINE_ uint32_t material_get_shader_id(RID p_material) { + Material *material = material_owner.getornull(p_material); + return material->shader_id; + } + _FORCE_INLINE_ MaterialData *material_get_data(RID p_material, ShaderType p_shader_type) { Material *material = material_owner.getornull(p_material); if (!material || material->shader_type != p_shader_type) { @@ -1388,6 +1426,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); @@ -1426,6 +1465,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; @@ -1436,13 +1482,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; @@ -1454,9 +1494,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; } } @@ -1664,6 +1714,10 @@ public: void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform); Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const; + _FORCE_INLINE_ bool skeleton_is_valid(RID p_skeleton) { + return skeleton_owner.getornull(p_skeleton) != nullptr; + } + _FORCE_INLINE_ RID skeleton_get_3d_uniform_set(RID p_skeleton, RID p_shader, uint32_t p_set) const { Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND_V(!skeleton, RID()); @@ -1827,8 +1881,8 @@ public: Color reflection_probe_get_ambient_color(RID p_probe) const; float reflection_probe_get_ambient_color_energy(RID p_probe) const; - void base_update_dependency(RID p_base, InstanceBaseDependency *p_instance); - void skeleton_update_dependency(RID p_skeleton, InstanceBaseDependency *p_instance); + void base_update_dependency(RID p_base, DependencyTracker *p_instance); + void skeleton_update_dependency(RID p_skeleton, DependencyTracker *p_instance); /* DECAL API */ @@ -1977,7 +2031,11 @@ public: _FORCE_INLINE_ float lightmap_get_probe_capture_update_speed() const { return lightmap_probe_capture_update_speed; } - + _FORCE_INLINE_ RID lightmap_get_texture(RID p_lightmap) const { + const Lightmap *lm = lightmap_owner.getornull(p_lightmap); + ERR_FAIL_COND_V(!lm, RID()); + return lm->light_texture; + } _FORCE_INLINE_ int32_t lightmap_get_array_index(RID p_lightmap) const { ERR_FAIL_COND_V(!using_lightmap_array, -1); //only for arrays const Lightmap *lm = lightmap_owner.getornull(p_lightmap); @@ -2078,8 +2136,8 @@ public: return particles->particles_transforms_buffer_uniform_set; } - virtual void particles_add_collision(RID p_particles, InstanceBaseDependency *p_instance); - virtual void particles_remove_collision(RID p_particles, InstanceBaseDependency *p_instance); + virtual void particles_add_collision(RID p_particles, RID p_particles_collision_instance); + virtual void particles_remove_collision(RID p_particles, RID p_particles_collision_instance); /* PARTICLES COLLISION */ @@ -2099,6 +2157,11 @@ public: virtual bool particles_collision_is_heightfield(RID p_particles_collision) const; RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const; + //used from 2D and 3D + virtual RID particles_collision_instance_create(RID p_collision); + virtual void particles_collision_instance_set_transform(RID p_collision_instance, const Transform &p_transform); + virtual void particles_collision_instance_set_active(RID p_collision_instance, bool p_active); + /* GLOBAL VARIABLES API */ virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value); diff --git a/servers/rendering/renderer_rd/shader_rd.cpp b/servers/rendering/renderer_rd/shader_rd.cpp index d1f07a354f..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()); @@ -351,6 +352,127 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) { } } +RS::ShaderNativeSourceCode ShaderRD::version_get_native_source_code(RID p_version) { + Version *version = version_owner.getornull(p_version); + RS::ShaderNativeSourceCode source_code; + ERR_FAIL_COND_V(!version, source_code); + + source_code.versions.resize(variant_defines.size()); + + for (int i = 0; i < source_code.versions.size(); i++) { + if (!is_compute) { + //vertex stage + + StringBuilder builder; + + builder.append(vertex_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++) { + builder.append(version->custom_defines[j].get_data()); + } + + builder.append(vertex_code0.get_data()); //first part of vertex + + builder.append(version->uniforms.get_data()); //uniforms (same for vertex and fragment) + + builder.append(vertex_code1.get_data()); //second part of vertex + + builder.append(version->vertex_globals.get_data()); // vertex globals + + builder.append(vertex_code2.get_data()); //third part of vertex + + builder.append(version->vertex_code.get_data()); // code + + builder.append(vertex_code3.get_data()); //fourth of vertex + + RS::ShaderNativeSourceCode::Version::Stage stage; + stage.name = "vertex"; + stage.code = builder.as_string(); + + source_code.versions.write[i].stages.push_back(stage); + } + + if (!is_compute) { + //fragment stage + + StringBuilder builder; + + 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++) { + builder.append(version->custom_defines[j].get_data()); + } + + builder.append(fragment_code0.get_data()); //first part of fragment + + builder.append(version->uniforms.get_data()); //uniforms (same for fragment and fragment) + + builder.append(fragment_code1.get_data()); //first part of fragment + + builder.append(version->fragment_globals.get_data()); // fragment globals + + builder.append(fragment_code2.get_data()); //third part of fragment + + builder.append(version->fragment_light.get_data()); // fragment light + + builder.append(fragment_code3.get_data()); //fourth part of fragment + + builder.append(version->fragment_code.get_data()); // fragment code + + builder.append(fragment_code4.get_data()); //fourth part of fragment + + RS::ShaderNativeSourceCode::Version::Stage stage; + stage.name = "fragment"; + stage.code = builder.as_string(); + + source_code.versions.write[i].stages.push_back(stage); + } + + if (is_compute) { + //compute stage + + StringBuilder builder; + + 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()); + + for (int j = 0; j < version->custom_defines.size(); j++) { + builder.append(version->custom_defines[j].get_data()); + } + + builder.append(compute_code0.get_data()); //first part of compute + + builder.append(version->uniforms.get_data()); //uniforms (same for compute and fragment) + + builder.append(compute_code1.get_data()); //second part of compute + + builder.append(version->compute_globals.get_data()); // compute globals + + builder.append(compute_code2.get_data()); //third part of compute + + builder.append(version->compute_code.get_data()); // code + + builder.append(compute_code3.get_data()); //fourth of compute + + RS::ShaderNativeSourceCode::Version::Stage stage; + stage.name = "compute"; + stage.code = builder.as_string(); + + source_code.versions.write[i].stages.push_back(stage); + } + } + + return source_code; +} + void ShaderRD::_compile_version(Version *p_version) { _clear_version(p_version); @@ -360,7 +482,7 @@ void ShaderRD::_compile_version(Version *p_version) { p_version->variants = memnew_arr(RID, variant_defines.size()); #if 1 - RendererCompositorRD::thread_work_pool.do_work(variant_defines.size(), this, &ShaderRD::_compile_variant, p_version); + RendererThreadPool::singleton->thread_work_pool.do_work(variant_defines.size(), this, &ShaderRD::_compile_variant, p_version); #else for (int i = 0; i < variant_defines.size(); i++) { _compile_variant(i, p_version); @@ -475,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 a80d08050a..e0f4dcf2d0 100644 --- a/servers/rendering/renderer_rd/shader_rd.h +++ b/servers/rendering/renderer_rd/shader_rd.h @@ -36,6 +36,7 @@ #include "core/templates/map.h" #include "core/templates/rid_owner.h" #include "core/variant/variant.h" +#include "servers/rendering_server.h" #include <stdio.h> /** @@ -98,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: @@ -133,6 +136,8 @@ public: void set_variant_enabled(int p_variant, bool p_enabled); bool is_variant_enabled(int p_variant) const; + RS::ShaderNativeSourceCode version_get_native_source_code(RID p_version); + void initialize(const Vector<String> &p_variant_defines, const String &p_general_defines = ""); virtual ~ShaderRD(); }; 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 2a7cae3b4c..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 @@ -497,7 +497,7 @@ void main() { vec2 shadow_vertex = vertex; { - float normal_depth = 1.0; + float normal_map_depth = 1.0; #if defined(NORMAL_MAP_USED) vec3 normal_map = vec3(0.0, 0.0, 1.0); @@ -511,7 +511,7 @@ FRAGMENT_SHADER_CODE /* clang-format on */ #if defined(NORMAL_MAP_USED) - normal = mix(vec3(0.0, 0.0, 1.0), normal_map * vec3(2.0, -2.0, 1.0) - vec3(1.0, -1.0, 0.0), normal_depth); + normal = mix(vec3(0.0, 0.0, 1.0), normal_map * vec3(2.0, -2.0, 1.0) - vec3(1.0, -1.0, 0.0), normal_map_depth); #endif } @@ -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 ea4237a45e..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; @@ -208,6 +208,15 @@ float raymarch(float distance, float distance_adv, vec3 from, vec3 direction) { return occlusion; //max(0.0,distance); } +float get_omni_attenuation(float distance, float inv_range, float decay) { + float nd = distance * inv_range; + nd *= nd; + nd *= nd; // nd^4 + nd = max(1.0 - nd, 0.0); + nd *= nd; // nd^2 + return nd * pow(max(distance, 0.0001), -decay); +} + bool compute_light_vector(uint light, vec3 pos, out float attenuation, out vec3 light_pos) { if (lights.data[light].type == LIGHT_TYPE_DIRECTIONAL) { light_pos = pos - lights.data[light].direction * length(vec3(params.limits)); @@ -220,17 +229,19 @@ bool compute_light_vector(uint light, vec3 pos, out float attenuation, out vec3 return false; } - attenuation = pow(clamp(1.0 - distance / lights.data[light].radius, 0.0001, 1.0), lights.data[light].attenuation); + attenuation = get_omni_attenuation(distance, 1.0 / lights.data[light].radius, lights.data[light].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/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 05f7637478..adccf1e712 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward.glsl @@ -89,33 +89,45 @@ MATERIAL_UNIFORMS } material; #endif -/* clang-format off */ - -VERTEX_SHADER_GLOBALS - -/* clang-format on */ - invariant gl_Position; -layout(location = 7) flat out uint instance_index; - #ifdef MODE_DUAL_PARABOLOID 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() { - instance_index = draw_call.instance_index; vec4 instance_custom = vec4(0.0); #if defined(COLOR_USED) color_interp = color_attrib; #endif + 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 = mat3(instances.data[instance_index].normal_transform); - if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH)) { + mat3 world_normal_matrix; + 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 (is_multimesh) { //multimesh, instances are for it uint offset = (instances.data[instance_index].flags >> INSTANCE_FLAGS_MULTIMESH_STRIDE_SHIFT) & INSTANCE_FLAGS_MULTIMESH_STRIDE_MASK; offset *= gl_InstanceIndex; @@ -144,10 +156,6 @@ void main() { matrix = transpose(matrix); world_matrix = world_matrix * matrix; world_normal_matrix = world_normal_matrix * mat3(matrix); - - } else { - //not a multimesh, instances are for multiple draw calls - instance_index += gl_InstanceIndex; } vec3 vertex = vertex_attrib; @@ -195,7 +203,7 @@ void main() { uv2_interp = uv2_attrib; #endif -#ifdef USE_OVERRIDE_POSITION +#ifdef OVERRIDE_POSITION vec4 position; #endif @@ -290,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); @@ -305,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.bake_uv2_offset) * 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; } @@ -345,18 +354,17 @@ layout(location = 5) in vec3 tangent_interp; layout(location = 6) in vec3 binormal_interp; #endif -layout(location = 7) flat in uint instance_index; - #ifdef MODE_DUAL_PARABOLOID 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 instances.data[instance_index].transform -#define world_normal_matrix instances.data[instance_index].normal_transform #define projection_matrix scene_data.projection_matrix #if defined(ENABLE_SSS) && defined(ENABLE_TRANSMITTANCE) @@ -545,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 @@ -557,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, @@ -565,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 @@ -574,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; @@ -585,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); @@ -595,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 @@ -612,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); @@ -656,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 @@ -682,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 @@ -692,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 @@ -700,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 @@ -712,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) @@ -723,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) @@ -732,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.. @@ -757,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) @@ -777,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) @@ -895,69 +904,39 @@ float sample_directional_soft_shadow(texture2D shadow, vec3 pssm_coord, vec2 tex #endif //USE_NO_SHADOWS -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); - float normalized_distance = light_length * lights.data[idx].inv_radius; - vec2 attenuation_energy = unpackHalf2x16(lights.data[idx].attenuation_energy); - float omni_attenuation = pow(max(1.0 - normalized_distance, 0.0), 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 get_omni_attenuation(float distance, float inv_range, float decay) { + float nd = distance * inv_range; + nd *= nd; + nd *= nd; // nd^4 + nd = max(1.0 - nd, 0.0); + nd *= nd; // nd^2 + return nd * pow(max(distance, 0.0001), -decay); +} +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 @@ -977,10 +956,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; @@ -988,7 +967,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; @@ -1016,7 +995,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++) { @@ -1024,7 +1003,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; @@ -1047,8 +1026,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; @@ -1062,101 +1042,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 @@ -1168,7 +1196,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, @@ -1176,6 +1204,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 @@ -1183,89 +1214,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); - float normalized_distance = light_length * lights.data[idx].inv_radius; - vec2 attenuation_energy = unpackHalf2x16(lights.data[idx].attenuation_energy); - float spot_attenuation = pow(max(1.0 - normalized_distance, 0.001), 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; @@ -1278,11 +1259,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; @@ -1299,7 +1280,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)); } @@ -1311,54 +1292,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 @@ -1370,7 +1390,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, @@ -1378,6 +1398,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 @@ -1401,11 +1424,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; @@ -1422,11 +1445,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; @@ -1445,7 +1468,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); } @@ -1456,7 +1479,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; @@ -1759,7 +1782,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; @@ -1774,7 +1797,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 @@ -1802,9 +1861,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 @@ -1812,10 +1869,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; @@ -1855,7 +1910,7 @@ void main() { vec3 normal_map = vec3(0.5); #endif - float normal_depth = 1.0; + float normal_map_depth = 1.0; vec2 screen_uv = gl_FragCoord.xy * scene_data.screen_pixel_size + scene_data.screen_pixel_size * 0.5; //account for center @@ -1931,7 +1986,7 @@ FRAGMENT_SHADER_CODE normal_map.xy = normal_map.xy * 2.0 - 1.0; normal_map.z = sqrt(max(0.0, 1.0 - dot(normal_map.xy, normal_map.xy))); //always ignore Z, as it can be RG packed, Z may be pos/neg, etc. - normal = normalize(mix(normal, tangent * normal_map.x + binormal * normal_map.y + normal * normal_map.z, normal_depth)); + normal = normalize(mix(normal, tangent * normal_map.x + binormal * normal_map.y + normal * normal_map.z, normal_map_depth)); #endif @@ -1953,77 +2008,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 & instances.data[instance_index].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].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].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; + } } } } + //pack albedo until needed again, saves 2 VGPRs in the meantime + #endif //not render depth /////////////////////// LIGHTING ////////////////////////////// @@ -2091,12 +2216,7 @@ 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 @@ -2124,10 +2244,10 @@ FRAGMENT_SHADER_CODE } 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 & 0xFFF; + uint ofs = instances.data[instance_index].gi_offset & 0xFFFF; vec3 uvw; 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 >> 12) & 0xFF); + 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 @@ -2263,17 +2383,17 @@ FRAGMENT_SHADER_CODE 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; @@ -2283,28 +2403,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; + + uint item_min; + uint item_max; + uint item_from; + uint item_to; - 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); + 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) { @@ -2318,6 +2479,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 @@ -2335,24 +2506,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++) { + // 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; + } + if (!bool(directional_lights.data[i].mask & instances.data[instance_index].layer_mask)) { continue; //not masked } - vec3 shadow_attenuation = vec3(1.0); - -#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; @@ -2366,8 +2552,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); @@ -2388,19 +2572,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); @@ -2420,19 +2591,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); @@ -2452,19 +2610,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); @@ -2485,20 +2630,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) { @@ -2572,130 +2703,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 & instances.data[instance_index].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 - light_process_omni(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, albedo, roughness, metallic, specular, specular_blob_intensity, + 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(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 & instances.data[instance_index].layer_mask)) { - continue; //not masked - } + uint item_min; + uint item_max; + uint item_from; + uint item_to; + + 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); - light_process_spot(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, albedo, roughness, metallic, specular, specular_blob_intensity, +#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 @@ -2707,173 +3115,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(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; - } + 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 @@ -2889,25 +3273,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 @@ -2919,22 +3286,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 17ed22f58a..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) @@ -13,8 +22,9 @@ layout(push_constant, binding = 0, std430) uniform DrawCall { uint instance_index; - uint pad; //16 bits minimum size - vec2 bake_uv2_offset; //used for bake to uv2, ignored otherwise + uint uv_offset; + uint pad0; + uint pad1; } draw_call; @@ -33,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) @@ -134,33 +66,24 @@ scene_data; #define INSTANCE_FLAGS_MULTIMESH_STRIDE_MASK 0x7 #define INSTANCE_FLAGS_SKELETON (1 << 19) +#define INSTANCE_FLAGS_NON_UNIFORM_SCALE (1 << 20) -struct InstanceData { - mat4 transform; - mat4 normal_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 = 0, binding = 4, std430) restrict readonly buffer Instances { - InstanceData data[]; +layout(set = 0, binding = 3, std430) restrict readonly buffer OmniLights { + LightData data[]; } -instances; +omni_lights; -layout(set = 0, binding = 5, std430) restrict readonly buffer 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; @@ -172,40 +95,29 @@ 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; -layout(set = 0, binding = 11) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES]; - struct LightmapCapture { vec4 sh[9]; }; -layout(set = 0, binding = 12, std140) restrict readonly buffer LightmapCaptures { +layout(set = 0, binding = 8, std140) restrict readonly buffer LightmapCaptures { LightmapCapture data[]; } lightmap_captures; -layout(set = 0, binding = 13) uniform texture2D decal_atlas; -layout(set = 0, binding = 14) 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 = 15, std430) restrict readonly buffer Decals { +layout(set = 0, binding = 11, std430) restrict readonly buffer Decals { DecalData data[]; } decals; -layout(set = 0, binding = 16) uniform utexture3D cluster_texture; - -layout(set = 0, binding = 17, std430) restrict readonly buffer ClusterData { - uint indices[]; -} -cluster_data; - -layout(set = 0, binding = 18) uniform texture2D directional_shadow_atlas; - -layout(set = 0, binding = 19, std430) restrict readonly buffer GlobalVariableData { +layout(set = 0, binding = 12, std430) restrict readonly buffer GlobalVariableData { vec4 data[]; } global_variables; @@ -219,7 +131,7 @@ struct SDFGIProbeCascadeData { float to_cell; // 1/bounds * grid_size }; -layout(set = 0, binding = 20, std140) uniform SDFGI { +layout(set = 0, binding = 13, std140) uniform SDFGI { vec3 grid_size; uint max_cascades; @@ -249,38 +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; -/* Set 1, Radiance */ + 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 + + 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; -#ifndef LOW_END_MODE -layout(set = 1, binding = 3) uniform texture3D gi_probe_textures[MAX_GI_PROBES]; +layout(set = 1, binding = 6) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES]; + +#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 = 4) uniform restrict writeonly uimage3D albedo_volume_grid; -layout(r32ui, set = 1, binding = 5) uniform restrict writeonly uimage3D emission_grid; -layout(r32ui, set = 1, binding = 6) uniform restrict writeonly uimage3D emission_aniso_grid; -layout(r32ui, set = 1, binding = 7) 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 @@ -289,17 +303,17 @@ layout(r32ui, set = 1, binding = 7) uniform restrict uimage3D geom_facing_grid; #else -layout(set = 1, binding = 4) uniform texture2D depth_buffer; -layout(set = 1, binding = 5) 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 = 6) uniform texture2D normal_roughness_buffer; -layout(set = 1, binding = 7) uniform texture2D ao_buffer; -layout(set = 1, binding = 8) uniform texture2D ambient_buffer; -layout(set = 1, binding = 9) uniform texture2D reflection_buffer; -layout(set = 1, binding = 10) uniform texture2DArray sdfgi_lightprobe_texture; -layout(set = 1, binding = 11) 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; @@ -317,22 +331,22 @@ struct GIProbeData { uint mipmaps; }; -layout(set = 1, binding = 12, std140) uniform GIProbes { +layout(set = 1, binding = 17, std140) uniform GIProbes { GIProbeData data[MAX_GI_PROBES]; } gi_probes; -layout(set = 1, binding = 13) 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 61e4bf5e18..5e8934adb4 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; @@ -112,11 +112,23 @@ vec2 octahedron_encode(vec3 n) { return n.xy; } +float get_omni_attenuation(float distance, float inv_range, float decay) { + float nd = distance * inv_range; + nd *= nd; + nd *= nd; // nd^4 + nd = max(1.0 - nd, 0.0); + nd *= nd; // nd^2 + return nd * pow(max(distance, 0.0001), -decay); +} + 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; @@ -134,10 +146,78 @@ 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.multibounce) { + 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 = (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; + 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] *= albedo; + } + } + } + +#endif + { uint rgbe = process_voxels.data[voxel_index].light; @@ -153,18 +233,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; @@ -184,22 +256,26 @@ void main() { direction = normalize(rel_vec); light_distance = length(rel_vec); rel_vec.y /= params.y_mult; - attenuation = pow(clamp(1.0 - length(rel_vec) / lights.data[i].radius, 0.0, 1.0), lights.data[i].attenuation); + attenuation = get_omni_attenuation(light_distance, 1.0 / lights.data[i].radius, lights.data[i].attenuation); + } break; case LIGHT_TYPE_SPOT: { vec3 rel_vec = lights.data[i].position - position; direction = normalize(rel_vec); light_distance = length(rel_vec); rel_vec.y /= params.y_mult; - attenuation = pow(clamp(1.0 - length(rel_vec) / lights.data[i].radius, 0.0, 1.0), 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); + attenuation = get_omni_attenuation(light_distance, 1.0 / lights.data[i].radius, lights.data[i].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; } @@ -282,65 +358,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/ssao.glsl b/servers/rendering/renderer_rd/shaders/ssao.glsl index 315ef8fa13..231f8f91ec 100644 --- a/servers/rendering/renderer_rd/shaders/ssao.glsl +++ b/servers/rendering/renderer_rd/shaders/ssao.glsl @@ -88,7 +88,7 @@ counter; layout(rg8, set = 2, binding = 0) uniform restrict writeonly image2D dest_image; // This push_constant is full - 128 bytes - if you need to add more data, consider adding to the uniform buffer instead -layout(push_constant, binding = 1, std430) uniform Params { +layout(push_constant, binding = 3, std430) uniform Params { ivec2 screen_size; int pass; int quality; diff --git a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl index 13b162f0c9..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); @@ -169,6 +193,51 @@ vec3 hash3f(uvec3 x) { return vec3(x & 0xFFFFF) / vec3(float(0xFFFFF)); } +float get_omni_attenuation(float distance, float inv_range, float decay) { + float nd = distance * inv_range; + nd *= nd; + nd *= nd; // nd^4 + nd = max(1.0 - nd, 0.0); + nd *= nd; // nd^2 + 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); @@ -184,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; @@ -191,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; @@ -257,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) * lights.data[i].inv_radius; - vec3 shadow_attenuation = vec3(1.0); +#ifdef USE_SUBGROUPS + item_from = subgroupBroadcastFirst(subgroupMin(item_from)); + item_to = subgroupBroadcastFirst(subgroupMax(item_to)); +#endif - if (d < 1.0) { - vec2 attenuation_energy = unpackHalf2x16(lights.data[i].attenuation_energy); - vec4 color_specular = unpackUnorm4x8(lights.data[i].color_specular); + 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 - float attenuation = pow(max(1.0 - d, 0.0), attenuation_energy.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 + uint light_index = 32 * i + bit; - vec3 light = attenuation_energy.y * color_specular.rgb / M_PI; + //if (!bool(omni_omni_lights.data[light_index].mask & draw_call.layer_mask)) { + // continue; //not masked + //} - vec4 shadow_color_enabled = unpackUnorm4x8(lights.data[i].shadow_color_enabled); + 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; - if (shadow_color_enabled.a > 0.5) { - //has shadow - vec4 v = vec4(view_pos, 1.0); + 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 splane = (lights.data[i].shadow_matrix * v); - float shadow_len = length(splane.xyz); //need to remember shadow len from here + vec3 light = omni_lights.data[light_index].color / M_PI; - splane.xyz = normalize(splane.xyz); - vec4 clamp_rect = lights.data[i].atlas_rect; + if (omni_lights.data[light_index].shadow_enabled) { + //has shadow + vec4 v = vec4(view_pos, 1.0); - if (splane.z >= 0.0) { - splane.z += 1.0; + vec4 splane = (omni_lights.data[light_index].shadow_matrix * v); + float shadow_len = length(splane.xyz); //need to remember shadow len from here - clamp_rect.y += clamp_rect.w; + splane.xyz = normalize(splane.xyz); + vec4 clamp_rect = omni_lights.data[light_index].atlas_rect; - } else { - splane.z = 1.0 - splane.z; - } + if (splane.z >= 0.0) { + splane.z += 1.0; + + clamp_rect.y += clamp_rect.w; - splane.xy /= splane.z; + } else { + splane.z = 1.0 - 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.z; - 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); + 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 - shadow_attenuation = mix(shadow_color_enabled.rgb, vec3(1.0), shadow); + float depth = texture(sampler2D(shadow_atlas, linear_sampler), splane.xy).r; + + 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) * lights.data[i].inv_radius; - vec3 shadow_attenuation = vec3(1.0); + uint item_min; + uint item_max; + uint item_from; + uint item_to; - if (d < 1.0) { - vec2 attenuation_energy = unpackHalf2x16(lights.data[i].attenuation_energy); - vec4 color_specular = unpackUnorm4x8(lights.data[i].color_specular); + cluster_get_item_range(cluster_spot_offset + params.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to); - float attenuation = pow(max(1.0 - d, 0.0), attenuation_energy.x); +#ifdef USE_SUBGROUPS + item_from = subgroupBroadcastFirst(subgroupMin(item_from)); + item_to = subgroupBroadcastFirst(subgroupMax(item_to)); +#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); + 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 light = attenuation_energy.y * color_specular.rgb / M_PI; + 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 - vec4 shadow_color_enabled = unpackUnorm4x8(lights.data[i].shadow_color_enabled); + //if (!bool(omni_lights.data[light_index].mask & draw_call.layer_mask)) { + // continue; //not masked + //} - if (shadow_color_enabled.a > 0.5) { - //has shadow - vec4 v = vec4(view_pos, 1.0); + uint light_index = 32 * i + bit; - vec4 splane = (lights.data[i].shadow_matrix * v); - splane /= splane.w; + 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; - 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); + 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); - shadow_attenuation = mix(shadow_color_enabled.rgb, vec3(1.0), shadow); - } + 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); + + 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; + } + } } } @@ -461,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..e8966414ab 100644 --- a/servers/rendering/renderer_scene.h +++ b/servers/rendering/renderer_scene.h @@ -95,7 +95,7 @@ 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 */ @@ -122,12 +122,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; @@ -140,6 +138,7 @@ public: 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; @@ -172,7 +171,7 @@ 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 */ @@ -180,6 +179,8 @@ 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 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 2e32c69cba..8067f9574c 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -135,7 +135,7 @@ void RendererSceneCull::_instance_pair(Instance *p_A, Instance *p_B) { idata.flags |= InstanceData::FLAG_GEOM_LIGHTING_DIRTY; } - } else if (self->pair_volumes_to_mesh && B->base_type == RS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { + } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && B->base_type == RS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -147,7 +147,7 @@ void RendererSceneCull::_instance_pair(Instance *p_A, Instance *p_B) { idata.flags |= InstanceData::FLAG_GEOM_REFLECTION_DIRTY; } - } else if (self->pair_volumes_to_mesh && B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { + } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_DECAL) && B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { InstanceDecalData *decal = static_cast<InstanceDecalData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -174,7 +174,7 @@ void RendererSceneCull::_instance_pair(Instance *p_A, Instance *p_B) { ((RendererSceneCull *)self)->_instance_queue_update(A, false, false); //need to update capture } - } else if (B->base_type == RS::INSTANCE_GI_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { + } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_GI_PROBE) && B->base_type == RS::INSTANCE_GI_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -195,7 +195,8 @@ void RendererSceneCull::_instance_pair(Instance *p_A, Instance *p_B) { InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data); gi_probe->lights.insert(A); } else if (B->base_type == RS::INSTANCE_PARTICLES_COLLISION && A->base_type == RS::INSTANCE_PARTICLES) { - RSG::storage->particles_add_collision(A->base, B); + InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(B->base_data); + RSG::storage->particles_add_collision(A->base, collision->instance); } } @@ -225,7 +226,7 @@ void RendererSceneCull::_instance_unpair(Instance *p_A, Instance *p_B) { idata.flags |= InstanceData::FLAG_GEOM_LIGHTING_DIRTY; } - } else if (self->pair_volumes_to_mesh && B->base_type == RS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { + } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && B->base_type == RS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -237,7 +238,7 @@ void RendererSceneCull::_instance_unpair(Instance *p_A, Instance *p_B) { idata.flags |= InstanceData::FLAG_GEOM_REFLECTION_DIRTY; } - } else if (self->pair_volumes_to_mesh && B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { + } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_DECAL) && B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { InstanceDecalData *decal = static_cast<InstanceDecalData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -264,7 +265,7 @@ void RendererSceneCull::_instance_unpair(Instance *p_A, Instance *p_B) { ((RendererSceneCull *)self)->_instance_queue_update(A, false, false); //need to update capture } - } else if (B->base_type == RS::INSTANCE_GI_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { + } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_GI_PROBE) && B->base_type == RS::INSTANCE_GI_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -284,7 +285,8 @@ void RendererSceneCull::_instance_unpair(Instance *p_A, Instance *p_B) { InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data); gi_probe->lights.erase(A); } else if (B->base_type == RS::INSTANCE_PARTICLES_COLLISION && A->base_type == RS::INSTANCE_PARTICLES) { - RSG::storage->particles_remove_collision(A->base, B); + InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(B->base_data); + RSG::storage->particles_remove_collision(A->base, collision->instance); } } @@ -386,6 +388,9 @@ void RendererSceneCull::_instance_update_mesh_instance(Instance *p_instance) { p_instance->mesh_instance = RID(); } + InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data); + scene_render->geometry_instance_set_mesh_instance(geom->geometry_instance, p_instance->mesh_instance); + if (p_instance->scenario && p_instance->array_index >= 0) { InstanceData &idata = p_instance->scenario->instance_data[p_instance->array_index]; if (p_instance->mesh_instance.is_valid()) { @@ -421,10 +426,17 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) { } switch (instance->base_type) { + case RS::INSTANCE_MESH: + case RS::INSTANCE_MULTIMESH: + case RS::INSTANCE_IMMEDIATE: + case RS::INSTANCE_PARTICLES: { + InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); + scene_render->geometry_instance_free(geom->geometry_instance); + } break; 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); } @@ -439,6 +451,10 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) { } scene_render->free(light->instance); } break; + case RS::INSTANCE_PARTICLES_COLLISION: { + InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(instance->base_data); + RSG::storage->free(collision->instance); + } break; case RS::INSTANCE_REFLECTION_PROBE: { InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(instance->base_data); scene_render->free(reflection_probe->instance); @@ -457,6 +473,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) { while (lightmap_data->users.front()) { instance_geometry_set_lightmap(lightmap_data->users.front()->get()->self, RID(), Rect2(), 0); } + scene_render->free(lightmap_data->instance); } break; case RS::INSTANCE_GI_PROBE: { InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(instance->base_data); @@ -514,8 +531,29 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) { case RS::INSTANCE_PARTICLES: { InstanceGeometryData *geom = memnew(InstanceGeometryData); instance->base_data = geom; + geom->geometry_instance = scene_render->geometry_instance_create(p_base); + + scene_render->geometry_instance_set_skeleton(geom->geometry_instance, instance->skeleton); + scene_render->geometry_instance_set_material_override(geom->geometry_instance, instance->material_override); + scene_render->geometry_instance_set_surface_materials(geom->geometry_instance, instance->materials); + scene_render->geometry_instance_set_transform(geom->geometry_instance, instance->transform, instance->aabb, instance->transformed_aabb); + scene_render->geometry_instance_set_layer_mask(geom->geometry_instance, instance->layer_mask); + scene_render->geometry_instance_set_lod_bias(geom->geometry_instance, instance->lod_bias); + scene_render->geometry_instance_set_use_baked_light(geom->geometry_instance, instance->baked_light); + scene_render->geometry_instance_set_use_dynamic_gi(geom->geometry_instance, instance->dynamic_gi); + scene_render->geometry_instance_set_cast_double_sided_shadows(geom->geometry_instance, instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED); + scene_render->geometry_instance_set_use_lightmap(geom->geometry_instance, RID(), instance->lightmap_uv_scale, instance->lightmap_slice_index); + if (instance->lightmap_sh.size() == 9) { + scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, instance->lightmap_sh.ptr()); + } } break; + case RS::INSTANCE_PARTICLES_COLLISION: { + InstanceParticlesCollisionData *collision = memnew(InstanceParticlesCollisionData); + collision->instance = RSG::storage->particles_collision_instance_create(p_base); + RSG::storage->particles_collision_instance_set_active(collision->instance, instance->visible); + instance->base_data = collision; + } break; case RS::INSTANCE_REFLECTION_PROBE: { InstanceReflectionProbeData *reflection_probe = memnew(InstanceReflectionProbeData); reflection_probe->owner = instance; @@ -533,7 +571,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) { case RS::INSTANCE_LIGHTMAP: { InstanceLightmapData *lightmap_data = memnew(InstanceLightmapData); instance->base_data = lightmap_data; - //lightmap_data->instance = scene_render->lightmap_data_instance_create(p_base); + lightmap_data->instance = scene_render->lightmap_instance_create(p_base); } break; case RS::INSTANCE_GI_PROBE: { InstanceGIProbeData *gi_probe = memnew(InstanceGIProbeData); @@ -558,7 +596,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) { } //forcefully update the dependency now, so if for some reason it gets removed, we can immediately clear it - RSG::storage->base_update_dependency(p_base, instance); + RSG::storage->base_update_dependency(p_base, &instance->dependency_tracker); } _instance_queue_update(instance, true, true); @@ -659,6 +697,11 @@ void RendererSceneCull::instance_set_layer_mask(RID p_instance, uint32_t p_mask) if (instance->scenario && instance->array_index >= 0) { instance->scenario->instance_data[instance->array_index].layer_mask = p_mask; } + + if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { + InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); + scene_render->geometry_instance_set_layer_mask(geom->geometry_instance, p_mask); + } } void RendererSceneCull::instance_set_transform(RID p_instance, const Transform &p_transform) { @@ -739,6 +782,22 @@ void RendererSceneCull::instance_set_visible(RID p_instance, bool p_visible) { } else if (instance->indexer_id.is_valid()) { _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); + } } inline bool is_geometry_instance(RenderingServer::InstanceType p_type) { @@ -782,12 +841,17 @@ void RendererSceneCull::instance_attach_skeleton(RID p_instance, RID p_skeleton) if (p_skeleton.is_valid()) { //update the dependency now, so if cleared, we remove it - RSG::storage->skeleton_update_dependency(p_skeleton, instance); + RSG::storage->skeleton_update_dependency(p_skeleton, &instance->dependency_tracker); } - _instance_update_mesh_instance(instance); - _instance_queue_update(instance, true, true); + + if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { + _instance_update_mesh_instance(instance); + + InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); + scene_render->geometry_instance_set_skeleton(geom->geometry_instance, p_skeleton); + } } void RendererSceneCull::instance_set_exterior(RID p_instance, bool p_enabled) { @@ -892,6 +956,11 @@ void RendererSceneCull::instance_geometry_set_flag(RID p_instance, RS::InstanceF } } + if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { + InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); + scene_render->geometry_instance_set_use_baked_light(geom->geometry_instance, p_enabled); + } + } break; case RS::INSTANCE_FLAG_USE_DYNAMIC_GI: { if (p_enabled == instance->dynamic_gi) { @@ -907,6 +976,11 @@ void RendererSceneCull::instance_geometry_set_flag(RID p_instance, RS::InstanceF //once out of octree, can be changed instance->dynamic_gi = p_enabled; + if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { + InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); + scene_render->geometry_instance_set_use_dynamic_gi(geom->geometry_instance, p_enabled); + } + } break; case RS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE: { instance->redraw_if_visible = p_enabled; @@ -948,6 +1022,11 @@ void RendererSceneCull::instance_geometry_set_cast_shadows_setting(RID p_instanc } } + if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { + InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); + scene_render->geometry_instance_set_cast_double_sided_shadows(geom->geometry_instance, instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED); + } + _instance_queue_update(instance, false, true); } @@ -957,6 +1036,11 @@ void RendererSceneCull::instance_geometry_set_material_override(RID p_instance, instance->material_override = p_material; _instance_queue_update(instance, false, true); + + if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { + InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); + scene_render->geometry_instance_set_material_override(geom->geometry_instance, p_material); + } } void RendererSceneCull::instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin) { @@ -981,9 +1065,17 @@ void RendererSceneCull::instance_geometry_set_lightmap(RID p_instance, RID p_lig instance->lightmap_uv_scale = p_lightmap_uv_scale; instance->lightmap_slice_index = p_slice_index; + RID lightmap_instance_rid; + if (lightmap_instance) { InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(lightmap_instance->base_data); lightmap_data->users.insert(instance); + lightmap_instance_rid = lightmap_data->instance; + } + + if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { + InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); + scene_render->geometry_instance_set_use_lightmap(geom->geometry_instance, lightmap_instance_rid, p_lightmap_uv_scale, p_slice_index); } } @@ -992,16 +1084,21 @@ void RendererSceneCull::instance_geometry_set_lod_bias(RID p_instance, float p_l ERR_FAIL_COND(!instance); instance->lod_bias = p_lod_bias; + + if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { + InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); + scene_render->geometry_instance_set_lod_bias(geom->geometry_instance, p_lod_bias); + } } void RendererSceneCull::instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); - Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter>::Element *E = instance->instance_shader_parameters.find(p_parameter); + Map<StringName, Instance::InstanceShaderParameter>::Element *E = instance->instance_shader_parameters.find(p_parameter); if (!E) { - RendererSceneRender::InstanceBase::InstanceShaderParameter isp; + Instance::InstanceShaderParameter isp; isp.index = -1; isp.info = PropertyInfo(); isp.value = p_value; @@ -1042,7 +1139,7 @@ void RendererSceneCull::instance_geometry_get_shader_parameter_list(RID p_instan const_cast<RendererSceneCull *>(this)->update_dirty_instances(); Vector<StringName> names; - for (Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter>::Element *E = instance->instance_shader_parameters.front(); E; E = E->next()) { + for (Map<StringName, Instance::InstanceShaderParameter>::Element *E = instance->instance_shader_parameters.front(); E; E = E->next()) { names.push_back(E->key()); } names.sort_custom<StringName::AlphCompare>(); @@ -1064,13 +1161,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); } } @@ -1079,9 +1176,7 @@ void RendererSceneCull::_update_instance(Instance *p_instance) { if (light->max_sdfgi_cascade != max_sdfgi_cascade) { light->max_sdfgi_cascade = max_sdfgi_cascade; //should most likely make sdfgi dirty in scenario } - } - - if (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE) { + } else if (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE) { InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(p_instance->base_data); scene_render->reflection_probe_instance_set_transform(reflection_probe->instance, p_instance->transform); @@ -1090,35 +1185,49 @@ void RendererSceneCull::_update_instance(Instance *p_instance) { InstanceData &idata = p_instance->scenario->instance_data[p_instance->array_index]; idata.flags |= InstanceData::FLAG_REFLECTION_PROBE_DIRTY; } - } - - if (p_instance->base_type == RS::INSTANCE_DECAL) { + } else if (p_instance->base_type == RS::INSTANCE_DECAL) { InstanceDecalData *decal = static_cast<InstanceDecalData *>(p_instance->base_data); scene_render->decal_instance_set_transform(decal->instance, p_instance->transform); - } + } else if (p_instance->base_type == RS::INSTANCE_LIGHTMAP) { + InstanceLightmapData *lightmap = static_cast<InstanceLightmapData *>(p_instance->base_data); - if (p_instance->base_type == RS::INSTANCE_GI_PROBE) { + scene_render->lightmap_instance_set_transform(lightmap->instance, p_instance->transform); + } else if (p_instance->base_type == RS::INSTANCE_GI_PROBE) { InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(p_instance->base_data); scene_render->gi_probe_instance_set_transform_to_data(gi_probe->probe_instance, p_instance->transform); - } - - if (p_instance->base_type == RS::INSTANCE_PARTICLES) { + } else if (p_instance->base_type == RS::INSTANCE_PARTICLES) { RSG::storage->particles_set_emission_transform(p_instance->base, p_instance->transform); - } + } else if (p_instance->base_type == RS::INSTANCE_PARTICLES_COLLISION) { + InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(p_instance->base_data); - if (p_instance->base_type == RS::INSTANCE_PARTICLES_COLLISION) { //remove materials no longer used and un-own them if (RSG::storage->particles_collision_is_heightfield(p_instance->base)) { heightfield_particle_colliders_update_list.insert(p_instance); } + RSG::storage->particles_collision_instance_set_transform(collision->instance, p_instance->transform); } if (p_instance->aabb.has_no_surface()) { return; } + if (p_instance->base_type == RS::INSTANCE_LIGHTMAP) { + //if this moved, update the captured objects + InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(p_instance->base_data); + //erase dependencies, since no longer a lightmap + + for (Set<Instance *>::Element *E = lightmap_data->geometries.front(); E; E = E->next()) { + Instance *geom = E->get(); + _instance_queue_update(geom, true, false); + } + } + + AABB new_aabb; + new_aabb = p_instance->transform.xform(p_instance->aabb); + p_instance->transformed_aabb = new_aabb; + if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data); //make sure lights are updated if it casts shadow @@ -1137,30 +1246,15 @@ void RendererSceneCull::_update_instance(Instance *p_instance) { if (!p_instance->lightmap_sh.is_empty()) { p_instance->lightmap_sh.clear(); //don't need SH p_instance->lightmap_target_sh.clear(); //don't need SH + scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, nullptr); } } - } - - if (p_instance->base_type == RS::INSTANCE_LIGHTMAP) { - //if this moved, update the captured objects - InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(p_instance->base_data); - //erase dependencies, since no longer a lightmap - for (Set<Instance *>::Element *E = lightmap_data->geometries.front(); E; E = E->next()) { - Instance *geom = E->get(); - _instance_queue_update(geom, true, false); - } + scene_render->geometry_instance_set_transform(geom->geometry_instance, p_instance->transform, p_instance->aabb, p_instance->transformed_aabb); } - p_instance->mirror = p_instance->transform.basis.determinant() < 0.0; - - AABB new_aabb; - - new_aabb = p_instance->transform.xform(p_instance->aabb); - - p_instance->transformed_aabb = new_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; } @@ -1195,17 +1289,26 @@ void RendererSceneCull::_update_instance(Instance *p_instance) { idata.flags = p_instance->base_type; //changing it means de-indexing, so this never needs to be changed later idata.base_rid = p_instance->base; switch (p_instance->base_type) { + case RS::INSTANCE_MESH: + case RS::INSTANCE_MULTIMESH: + case RS::INSTANCE_IMMEDIATE: + case RS::INSTANCE_PARTICLES: { + idata.instance_geometry = static_cast<InstanceGeometryData *>(p_instance->base_data)->geometry_instance; + } break; case RS::INSTANCE_LIGHT: { - idata.instance_data_rid = static_cast<InstanceLightData *>(p_instance->base_data)->instance; + idata.instance_data_rid = static_cast<InstanceLightData *>(p_instance->base_data)->instance.get_id(); } break; case RS::INSTANCE_REFLECTION_PROBE: { - idata.instance_data_rid = static_cast<InstanceReflectionProbeData *>(p_instance->base_data)->instance; + idata.instance_data_rid = static_cast<InstanceReflectionProbeData *>(p_instance->base_data)->instance.get_id(); } break; case RS::INSTANCE_DECAL: { - idata.instance_data_rid = static_cast<InstanceDecalData *>(p_instance->base_data)->instance; + idata.instance_data_rid = static_cast<InstanceDecalData *>(p_instance->base_data)->instance.get_id(); + } break; + case RS::INSTANCE_LIGHTMAP: { + idata.instance_data_rid = static_cast<InstanceLightmapData *>(p_instance->base_data)->instance.get_id(); } break; case RS::INSTANCE_GI_PROBE: { - idata.instance_data_rid = static_cast<InstanceGIProbeData *>(p_instance->base_data)->probe_instance; + idata.instance_data_rid = static_cast<InstanceGIProbeData *>(p_instance->base_data)->probe_instance.get_id(); } break; default: { } @@ -1258,10 +1361,8 @@ void RendererSceneCull::_update_instance(Instance *p_instance) { pair.pair_mask |= 1 << RS::INSTANCE_GI_PROBE; pair.pair_mask |= 1 << RS::INSTANCE_LIGHTMAP; - if (pair_volumes_to_mesh) { - pair.pair_mask |= 1 << RS::INSTANCE_DECAL; - pair.pair_mask |= 1 << RS::INSTANCE_REFLECTION_PROBE; - } + pair.pair_mask |= geometry_instance_pair_mask; + pair.bvh2 = &p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES]; } else if (p_instance->base_type == RS::INSTANCE_LIGHT) { pair.pair_mask |= RS::INSTANCE_GEOMETRY_MASK; @@ -1271,7 +1372,10 @@ void RendererSceneCull::_update_instance(Instance *p_instance) { pair.pair_mask |= (1 << RS::INSTANCE_GI_PROBE); pair.bvh2 = &p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES]; } - } else if (pair_volumes_to_mesh && (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE || p_instance->base_type == RS::INSTANCE_DECAL)) { + } else if (geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE)) { + pair.pair_mask = RS::INSTANCE_GEOMETRY_MASK; + pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY]; + } else if (geometry_instance_pair_mask & (1 << RS::INSTANCE_DECAL) && (p_instance->base_type == RS::INSTANCE_DECAL)) { pair.pair_mask = RS::INSTANCE_GEOMETRY_MASK; pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY]; } else if (p_instance->base_type == RS::INSTANCE_PARTICLES_COLLISION) { @@ -1325,10 +1429,12 @@ void RendererSceneCull::_unpair_instance(Instance *p_instance) { p_instance->array_index = -1; if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) { // Clear these now because the InstanceData containing the dirty flags is gone - p_instance->light_instances.clear(); - p_instance->reflection_probe_instances.clear(); - //p_instance->decal_instances.clear(); will implement later - p_instance->gi_probe_instances.clear(); + InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data); + + scene_render->geometry_instance_pair_light_instances(geom->geometry_instance, nullptr, 0); + scene_render->geometry_instance_pair_reflection_probe_instances(geom->geometry_instance, nullptr, 0); + scene_render->geometry_instance_pair_decal_instances(geom->geometry_instance, nullptr, 0); + scene_render->geometry_instance_pair_gi_probe_instances(geom->geometry_instance, nullptr, 0); } } @@ -1486,6 +1592,8 @@ void RendererSceneCull::_update_instance_lightmap_captures(Instance *p_instance) } } } + + scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, p_instance->lightmap_sh.ptr()); } void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_index, Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect) { @@ -1798,6 +1906,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)); @@ -1814,7 +1925,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()); @@ -1835,6 +1945,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) { @@ -1849,16 +1961,21 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons } } - geometry_instances_to_shadow_render.push_back(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); @@ -1888,7 +2005,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()); @@ -1907,7 +2023,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]; @@ -1922,22 +2038,28 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons } } - geometry_instances_to_shadow_render.push_back(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); @@ -1946,7 +2068,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()); @@ -1965,7 +2086,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]; @@ -1980,13 +2101,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(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; } @@ -2039,14 +2161,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); @@ -2126,9 +2247,226 @@ 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::_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::_frustum_cull_threaded(uint32_t p_thread, FrustumCullData *cull_data) { + uint32_t cull_total = cull_data->scenario->instance_data.size(); + uint32_t total_threads = RendererThreadPool::singleton->thread_work_pool.get_thread_count(); + uint32_t cull_from = p_thread * cull_total / total_threads; + uint32_t cull_to = (p_thread + 1 == total_threads) ? cull_total : ((p_thread + 1) * cull_total / total_threads); + + _frustum_cull(*cull_data, frustum_cull_result_threads[p_thread], cull_from, cull_to); +} + +void RendererSceneCull::_frustum_cull(FrustumCullData &cull_data, FrustumCullResult &cull_result, uint64_t p_from, uint64_t p_to) { + uint64_t frame_number = RSG::rasterizer->get_frame_number(); + float lightmap_probe_update_speed = RSG::storage->lightmap_get_probe_capture_update_speed() * RSG::rasterizer->get_frame_delta_time(); + + uint32_t sdfgi_last_light_index = 0xFFFFFFFF; + uint32_t sdfgi_last_light_cascade = 0xFFFFFFFF; + + RID instance_pair_buffer[MAX_INSTANCE_PAIRS]; + + for (uint64_t i = p_from; i < p_to; i++) { + bool mesh_visible = false; + + if (cull_data.scenario->instance_aabbs[i].in_frustum(cull_data.cull->frustum)) { + InstanceData &idata = cull_data.scenario->instance_data[i]; + uint32_t base_type = idata.flags & InstanceData::FLAG_BASE_TYPE_MASK; + + if ((cull_data.visible_layers & idata.layer_mask) == 0) { + //failure + } else if (base_type == RS::INSTANCE_LIGHT) { + cull_result.lights.push_back(idata.instance); + cull_result.light_instances.push_back(RID::from_uint64(idata.instance_data_rid)); + if (cull_data.shadow_atlas.is_valid() && RSG::storage->light_has_shadow(idata.base_rid)) { + scene_render->light_instance_mark_visible(RID::from_uint64(idata.instance_data_rid)); //mark it visible for shadow allocation later + } + + } else if (base_type == RS::INSTANCE_REFLECTION_PROBE) { + if (cull_data.render_reflection_probe != idata.instance) { + //avoid entering The Matrix + + if ((idata.flags & InstanceData::FLAG_REFLECTION_PROBE_DIRTY) || scene_render->reflection_probe_instance_needs_redraw(RID::from_uint64(idata.instance_data_rid))) { + InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(idata.instance->base_data); + cull_data.cull->lock.lock(); + if (!reflection_probe->update_list.in_list()) { + reflection_probe->render_step = 0; + reflection_probe_render_list.add_last(&reflection_probe->update_list); + } + cull_data.cull->lock.unlock(); + + idata.flags &= ~uint32_t(InstanceData::FLAG_REFLECTION_PROBE_DIRTY); + } + + if (scene_render->reflection_probe_instance_has_reflection(RID::from_uint64(idata.instance_data_rid))) { + cull_result.reflections.push_back(RID::from_uint64(idata.instance_data_rid)); + } + } + } else if (base_type == RS::INSTANCE_DECAL) { + cull_result.decals.push_back(RID::from_uint64(idata.instance_data_rid)); + + } else if (base_type == RS::INSTANCE_GI_PROBE) { + InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(idata.instance->base_data); + cull_data.cull->lock.lock(); + if (!gi_probe->update_element.in_list()) { + gi_probe_update_list.add(&gi_probe->update_element); + } + cull_data.cull->lock.unlock(); + cull_result.gi_probes.push_back(RID::from_uint64(idata.instance_data_rid)); + + } else if (base_type == RS::INSTANCE_LIGHTMAP) { + cull_result.gi_probes.push_back(RID::from_uint64(idata.instance_data_rid)); + } else if (((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) && !(idata.flags & InstanceData::FLAG_CAST_SHADOWS_ONLY)) { + bool keep = true; + + if (idata.flags & InstanceData::FLAG_REDRAW_IF_VISIBLE) { + RenderingServerDefault::redraw_request(); + } + + if (base_type == RS::INSTANCE_MESH) { + mesh_visible = true; + } else if (base_type == RS::INSTANCE_PARTICLES) { + //particles visible? process them + if (RSG::storage->particles_is_inactive(idata.base_rid)) { + //but if nothing is going on, don't do it. + keep = false; + } else { + cull_data.cull->lock.lock(); + RSG::storage->particles_request_process(idata.base_rid); + cull_data.cull->lock.unlock(); + RSG::storage->particles_set_view_axis(idata.base_rid, -cull_data.cam_transform.basis.get_axis(2).normalized()); + //particles visible? request redraw + RenderingServerDefault::redraw_request(); + } + } + + if (geometry_instance_pair_mask & (1 << RS::INSTANCE_LIGHT) && (idata.flags & InstanceData::FLAG_GEOM_LIGHTING_DIRTY)) { + InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); + uint32_t idx = 0; + + for (Set<Instance *>::Element *E = geom->lights.front(); E; E = E->next()) { + InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data); + instance_pair_buffer[idx++] = light->instance; + if (idx == MAX_INSTANCE_PAIRS) { + break; + } + } + + scene_render->geometry_instance_pair_light_instances(geom->geometry_instance, instance_pair_buffer, idx); + idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_LIGHTING_DIRTY); + } + + if (geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && (idata.flags & InstanceData::FLAG_GEOM_REFLECTION_DIRTY)) { + InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); + uint32_t idx = 0; + + for (Set<Instance *>::Element *E = geom->reflection_probes.front(); E; E = E->next()) { + InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(E->get()->base_data); + + instance_pair_buffer[idx++] = reflection_probe->instance; + if (idx == MAX_INSTANCE_PAIRS) { + break; + } + } + + scene_render->geometry_instance_pair_reflection_probe_instances(geom->geometry_instance, instance_pair_buffer, idx); + idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_REFLECTION_DIRTY); + } + + if (geometry_instance_pair_mask & (1 << RS::INSTANCE_DECAL) && (idata.flags & InstanceData::FLAG_GEOM_DECAL_DIRTY)) { + //InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); + //todo for GLES3 + idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_DECAL_DIRTY); + /*for (Set<Instance *>::Element *E = geom->dec.front(); E; E = E->next()) { + InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(E->get()->base_data); + + instance_pair_buffer[idx++] = reflection_probe->instance; + if (idx==MAX_INSTANCE_PAIRS) { + break; + } + }*/ + //scene_render->geometry_instance_pair_decal_instances(geom->geometry_instance, light_instances, idx); + } + + if (idata.flags & InstanceData::FLAG_GEOM_GI_PROBE_DIRTY) { + InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); + uint32_t idx = 0; + for (Set<Instance *>::Element *E = geom->gi_probes.front(); E; E = E->next()) { + InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(E->get()->base_data); + + instance_pair_buffer[idx++] = gi_probe->probe_instance; + if (idx == MAX_INSTANCE_PAIRS) { + break; + } + } + + scene_render->geometry_instance_pair_gi_probe_instances(geom->geometry_instance, instance_pair_buffer, idx); + idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_GI_PROBE_DIRTY); + } + + if ((idata.flags & InstanceData::FLAG_LIGHTMAP_CAPTURE) && idata.instance->last_frame_pass != frame_number && !idata.instance->lightmap_target_sh.is_empty() && !idata.instance->lightmap_sh.is_empty()) { + InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); + Color *sh = idata.instance->lightmap_sh.ptrw(); + const Color *target_sh = idata.instance->lightmap_target_sh.ptr(); + for (uint32_t j = 0; j < 9; j++) { + sh[j] = sh[j].lerp(target_sh[j], MIN(1.0, lightmap_probe_update_speed)); + } + scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, sh); + idata.instance->last_frame_pass = frame_number; + } + + if (keep) { + cull_result.geometry_instances.push_back(idata.instance_geometry); + } + } + } + + for (uint32_t j = 0; j < cull_data.cull->shadow_count; j++) { + for (uint32_t k = 0; k < cull_data.cull->shadows[j].cascade_count; k++) { + if (cull_data.scenario->instance_aabbs[i].in_frustum(cull_data.cull->shadows[j].cascades[k].frustum)) { + InstanceData &idata = cull_data.scenario->instance_data[i]; + uint32_t base_type = idata.flags & InstanceData::FLAG_BASE_TYPE_MASK; + + if (((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) && idata.flags & InstanceData::FLAG_CAST_SHADOWS) { + cull_result.directional_shadows[j].cascade_geometry_instances[k].push_back(idata.instance_geometry); + mesh_visible = true; + } + } + } + } + + for (uint32_t j = 0; j < cull_data.cull->sdfgi.region_count; j++) { + if (cull_data.scenario->instance_aabbs[i].in_aabb(cull_data.cull->sdfgi.region_aabb[j])) { + InstanceData &idata = cull_data.scenario->instance_data[i]; + uint32_t base_type = idata.flags & InstanceData::FLAG_BASE_TYPE_MASK; + + if (base_type == RS::INSTANCE_LIGHT) { + InstanceLightData *instance_light = (InstanceLightData *)idata.instance->base_data; + if (instance_light->bake_mode == RS::LIGHT_BAKE_STATIC && cull_data.cull->sdfgi.region_cascade[j] <= instance_light->max_sdfgi_cascade) { + if (sdfgi_last_light_index != i || sdfgi_last_light_cascade != cull_data.cull->sdfgi.region_cascade[j]) { + sdfgi_last_light_index = i; + sdfgi_last_light_cascade = cull_data.cull->sdfgi.region_cascade[j]; + cull_result.sdfgi_cascade_lights[sdfgi_last_light_cascade].push_back(instance_light->instance); + } + } + } else if ((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) { + if (idata.flags & InstanceData::FLAG_USES_BAKED_LIGHT) { + cull_result.sdfgi_region_geometry_instances[j].push_back(idata.instance_geometry); + mesh_visible = true; + } + } + } + } + + if (mesh_visible && cull_data.scenario->instance_data[i].flags & InstanceData::FLAG_USES_MESH_INSTANCE) { + cull_result.mesh_instances.push_back(cull_data.scenario->instance_data[i].instance->mesh_instance); + } + } +} + +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 @@ -2142,6 +2480,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) } @@ -2153,9 +2492,6 @@ void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const Ca Plane near_plane(p_cam_transform.origin, -p_cam_transform.basis.get_axis(2).normalized()); - uint64_t frame_number = RSG::rasterizer->get_frame_number(); - float lightmap_probe_update_speed = RSG::storage->lightmap_get_probe_capture_update_speed() * RSG::rasterizer->get_frame_delta_time(); - /* STEP 2 - CULL */ cull.frustum = Frustum(planes); @@ -2163,13 +2499,6 @@ void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const Ca Vector<RID> directional_lights; // directional lights { - //reset shadows - for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) { - for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) { - cull.shadows[i].cascades[j].cull_result.clear(); - } - } - cull.shadow_count = 0; Vector<Instance *> lights_with_shadow; @@ -2206,18 +2535,7 @@ void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const Ca { //sdfgi cull.sdfgi.region_count = 0; - for (int i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) { - cull.sdfgi.region_cull_result[i].clear(); - } - - for (int i = 0; i < SDFGI_MAX_CASCADES; i++) { - cull.sdfgi.cascade_lights[i].clear(); - } - if (p_render_buffers.is_valid()) { - for (int i = 0; i < SDFGI_MAX_CASCADES; i++) { - cull.sdfgi.cascade_lights[i].clear(); - } cull.sdfgi.cascade_light_count = 0; uint32_t prev_cascade = 0xFFFFFFFF; @@ -2239,209 +2557,53 @@ void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const Ca } } - { - //pre-clear results - geometry_instances_to_render.clear(); - light_cull_result.clear(); - lightmap_cull_result.clear(); - reflection_probe_instance_cull_result.clear(); - light_instance_cull_result.clear(); - gi_probe_instance_cull_result.clear(); - lightmap_cull_result.clear(); - decal_instance_cull_result.clear(); - mesh_instance_cull_result.clear(); - } + frustum_cull_result.clear(); { - uint64_t cull_count = scenario->instance_data.size(); - uint32_t sdfgi_last_light_index = 0xFFFFFFFF; - uint32_t sdfgi_last_light_cascade = 0xFFFFFFFF; - - for (uint64_t i = 0; i < cull_count; i++) { - bool mesh_visible = false; - - if (scenario->instance_aabbs[i].in_frustum(cull.frustum)) { - InstanceData &idata = scenario->instance_data[i]; - uint32_t base_type = idata.flags & InstanceData::FLAG_BASE_TYPE_MASK; - - if ((p_visible_layers & idata.layer_mask) == 0) { - //failure - } else if (base_type == RS::INSTANCE_LIGHT) { - light_cull_result.push_back(idata.instance); - light_instance_cull_result.push_back(idata.instance_data_rid); - if (p_shadow_atlas.is_valid() && RSG::storage->light_has_shadow(idata.base_rid)) { - scene_render->light_instance_mark_visible(idata.instance_data_rid); //mark it visible for shadow allocation later - } - - } else if (base_type == RS::INSTANCE_REFLECTION_PROBE) { - if (render_reflection_probe != idata.instance) { - //avoid entering The Matrix - - if ((idata.flags & InstanceData::FLAG_REFLECTION_PROBE_DIRTY) || scene_render->reflection_probe_instance_needs_redraw(idata.instance_data_rid)) { - InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(idata.instance->base_data); - cull.lock.lock(); - if (!reflection_probe->update_list.in_list()) { - reflection_probe->render_step = 0; - reflection_probe_render_list.add_last(&reflection_probe->update_list); - } - cull.lock.unlock(); - - idata.flags &= ~uint32_t(InstanceData::FLAG_REFLECTION_PROBE_DIRTY); - } - - if (scene_render->reflection_probe_instance_has_reflection(idata.instance_data_rid)) { - reflection_probe_instance_cull_result.push_back(idata.instance_data_rid); - } - } - } else if (base_type == RS::INSTANCE_DECAL) { - decal_instance_cull_result.push_back(idata.instance_data_rid); - - } else if (base_type == RS::INSTANCE_GI_PROBE) { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(idata.instance->base_data); - cull.lock.lock(); - if (!gi_probe->update_element.in_list()) { - gi_probe_update_list.add(&gi_probe->update_element); - } - cull.lock.unlock(); - gi_probe_instance_cull_result.push_back(idata.instance_data_rid); - - } else if (base_type == RS::INSTANCE_LIGHTMAP) { - lightmap_cull_result.push_back(idata.instance); - } else if (((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) && !(idata.flags & InstanceData::FLAG_CAST_SHADOWS_ONLY)) { - bool keep = true; - - if (idata.flags & InstanceData::FLAG_REDRAW_IF_VISIBLE) { - RenderingServerDefault::redraw_request(); - } - - if (base_type == RS::INSTANCE_MESH) { - mesh_visible = true; - } else if (base_type == RS::INSTANCE_PARTICLES) { - //particles visible? process them - if (RSG::storage->particles_is_inactive(idata.base_rid)) { - //but if nothing is going on, don't do it. - keep = false; - } else { - cull.lock.lock(); - RSG::storage->particles_request_process(idata.base_rid); - cull.lock.unlock(); - RSG::storage->particles_set_view_axis(idata.base_rid, -p_cam_transform.basis.get_axis(2).normalized()); - //particles visible? request redraw - RenderingServerDefault::redraw_request(); - } - } - - if (pair_volumes_to_mesh && (idata.flags & InstanceData::FLAG_GEOM_LIGHTING_DIRTY)) { - InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); - int l = 0; - //only called when lights AABB enter/exit this geometry - idata.instance->light_instances.resize(geom->lights.size()); - - for (Set<Instance *>::Element *E = geom->lights.front(); E; E = E->next()) { - InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data); - - idata.instance->light_instances.write[l++] = light->instance; - } - - idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_LIGHTING_DIRTY); - } - - if (pair_volumes_to_mesh && (idata.flags & InstanceData::FLAG_GEOM_REFLECTION_DIRTY)) { - InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); - int l = 0; - //only called when reflection probe AABB enter/exit this geometry - idata.instance->reflection_probe_instances.resize(geom->reflection_probes.size()); - - for (Set<Instance *>::Element *E = geom->reflection_probes.front(); E; E = E->next()) { - InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(E->get()->base_data); - - idata.instance->reflection_probe_instances.write[l++] = reflection_probe->instance; - } - - idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_REFLECTION_DIRTY); - } - - if (pair_volumes_to_mesh && (idata.flags & InstanceData::FLAG_GEOM_DECAL_DIRTY)) { - //InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); - //todo for GLES3 - idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_DECAL_DIRTY); - } - - if (idata.flags & InstanceData::FLAG_GEOM_GI_PROBE_DIRTY) { - InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); - int l = 0; - //only called when reflection probe AABB enter/exit this geometry - idata.instance->gi_probe_instances.resize(geom->gi_probes.size()); - - for (Set<Instance *>::Element *E = geom->gi_probes.front(); E; E = E->next()) { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(E->get()->base_data); - - idata.instance->gi_probe_instances.write[l++] = gi_probe->probe_instance; - } - - idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_GI_PROBE_DIRTY); - } - - if ((idata.flags & InstanceData::FLAG_LIGHTMAP_CAPTURE) && idata.instance->last_frame_pass != frame_number && !idata.instance->lightmap_target_sh.is_empty() && !idata.instance->lightmap_sh.is_empty()) { - Color *sh = idata.instance->lightmap_sh.ptrw(); - const Color *target_sh = idata.instance->lightmap_target_sh.ptr(); - for (uint32_t j = 0; j < 9; j++) { - sh[j] = sh[j].lerp(target_sh[j], MIN(1.0, lightmap_probe_update_speed)); - } - idata.instance->last_frame_pass = frame_number; - } - - if (keep) { - geometry_instances_to_render.push_back(idata.instance); - } - } - } - - for (uint32_t j = 0; j < cull.shadow_count; j++) { - for (uint32_t k = 0; k < cull.shadows[j].cascade_count; k++) { - if (scenario->instance_aabbs[i].in_frustum(cull.shadows[j].cascades[k].frustum)) { - InstanceData &idata = scenario->instance_data[i]; - uint32_t base_type = idata.flags & InstanceData::FLAG_BASE_TYPE_MASK; - - if (((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) && idata.flags & InstanceData::FLAG_CAST_SHADOWS) { - cull.shadows[j].cascades[k].cull_result.push_back(idata.instance); - mesh_visible = true; - } - } - } + uint64_t cull_from = 0; + uint64_t cull_to = scenario->instance_data.size(); + + FrustumCullData cull_data; + + //prepare for eventual thread usage + cull_data.cull = &cull; + cull_data.scenario = scenario; + cull_data.shadow_atlas = p_shadow_atlas; + cull_data.cam_transform = p_cam_transform; + cull_data.visible_layers = p_visible_layers; + cull_data.render_reflection_probe = render_reflection_probe; +//#define DEBUG_CULL_TIME +#ifdef DEBUG_CULL_TIME + uint64_t time_from = OS::get_singleton()->get_ticks_usec(); +#endif + if (cull_to > thread_cull_threshold) { + //multiple threads + for (uint32_t i = 0; i < frustum_cull_result_threads.size(); i++) { + frustum_cull_result_threads[i].clear(); } - for (uint32_t j = 0; j < cull.sdfgi.region_count; j++) { - if (scenario->instance_aabbs[i].in_aabb(cull.sdfgi.region_aabb[j])) { - InstanceData &idata = scenario->instance_data[i]; - uint32_t base_type = idata.flags & InstanceData::FLAG_BASE_TYPE_MASK; + RendererThreadPool::singleton->thread_work_pool.do_work(frustum_cull_result_threads.size(), this, &RendererSceneCull::_frustum_cull_threaded, &cull_data); - if (base_type == RS::INSTANCE_LIGHT) { - InstanceLightData *instance_light = (InstanceLightData *)idata.instance->base_data; - if (instance_light->bake_mode == RS::LIGHT_BAKE_STATIC && cull.sdfgi.region_cascade[j] <= instance_light->max_sdfgi_cascade) { - if (sdfgi_last_light_index != i || sdfgi_last_light_cascade != cull.sdfgi.region_cascade[j]) { - sdfgi_last_light_index = i; - sdfgi_last_light_cascade = cull.sdfgi.region_cascade[j]; - cull.sdfgi.cascade_lights[sdfgi_last_light_cascade].push_back(instance_light->instance); - } - } - } else if ((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) { - if (idata.flags & InstanceData::FLAG_USES_BAKED_LIGHT) { - cull.sdfgi.region_cull_result[j].push_back(idata.instance); - mesh_visible = true; - } - } - } + for (uint32_t i = 0; i < frustum_cull_result_threads.size(); i++) { + frustum_cull_result.append_from(frustum_cull_result_threads[i]); } - if (mesh_visible && scenario->instance_data[i].flags & InstanceData::FLAG_USES_MESH_INSTANCE) { - mesh_instance_cull_result.push_back(scenario->instance_data[i].instance->mesh_instance); - } + } else { + //single threaded + _frustum_cull(cull_data, frustum_cull_result, cull_from, cull_to); } - if (mesh_instance_cull_result.size()) { - for (uint64_t i = 0; i < mesh_instance_cull_result.size(); i++) { - RSG::storage->mesh_instance_check_for_update(mesh_instance_cull_result[i]); +#ifdef DEBUG_CULL_TIME + static float time_avg = 0; + static uint32_t time_count = 0; + time_avg += double(OS::get_singleton()->get_ticks_usec() - time_from) / 1000.0; + time_count++; + print_line("time taken: " + rtos(time_avg / time_count)); +#endif + + if (frustum_cull_result.mesh_instances.size()) { + for (uint64_t i = 0; i < frustum_cull_result.mesh_instances.size(); i++) { + RSG::storage->mesh_instance_check_for_update(frustum_cull_result.mesh_instances[i]); } RSG::storage->update_mesh_instances(); } @@ -2449,64 +2611,30 @@ 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, c.cull_result, 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, cull.sdfgi.region_cull_result[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 (cull.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, cull.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); - for (uint32_t i = 0; i < (uint32_t)light_cull_result.size(); i++) { - Instance *ins = light_cull_result[i]; + // Positional Shadowss + for (uint32_t i = 0; i < (uint32_t)frustum_cull_result.lights.size(); i++) { + Instance *ins = frustum_cull_result.lights[i]; if (!p_shadow_atlas.is_valid() || !RSG::storage->light_has_shadow(ins->base)) { continue; @@ -2591,19 +2719,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++) { - light_instance_cull_result.push_back(directional_lights[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) { @@ -2627,21 +2814,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, geometry_instances_to_render, light_instance_cull_result, reflection_probe_instance_cull_result, gi_probe_instance_cull_result, decal_instance_cull_result, lightmap_cull_result, 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 @@ -2654,7 +2826,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::InstanceBase *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RendererSceneRender::InstanceBase *>(), 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 } @@ -2717,8 +2889,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 @@ -2929,7 +3100,9 @@ void RendererSceneCull::render_probes() { update_lights = true; } - geometry_instances_to_render.clear(); + frustum_cull_result.geometry_instances.clear(); + + RID instance_pair_buffer[MAX_INSTANCE_PAIRS]; for (Set<Instance *>::Element *E = probe->dynamic_geometries.front(); E; E = E->next()) { Instance *ins = E->get(); @@ -2939,24 +3112,25 @@ void RendererSceneCull::render_probes() { InstanceGeometryData *geom = (InstanceGeometryData *)ins->base_data; if (ins->scenario && ins->array_index >= 0 && (ins->scenario->instance_data[ins->array_index].flags & InstanceData::FLAG_GEOM_GI_PROBE_DIRTY)) { - //giprobes may be dirty, so update - int l = 0; - //only called when reflection probe AABB enter/exit this geometry - ins->gi_probe_instances.resize(geom->gi_probes.size()); - + uint32_t idx = 0; for (Set<Instance *>::Element *F = geom->gi_probes.front(); F; F = F->next()) { InstanceGIProbeData *gi_probe2 = static_cast<InstanceGIProbeData *>(F->get()->base_data); - ins->gi_probe_instances.write[l++] = gi_probe2->probe_instance; + instance_pair_buffer[idx++] = gi_probe2->probe_instance; + if (idx == MAX_INSTANCE_PAIRS) { + break; + } } + scene_render->geometry_instance_pair_gi_probe_instances(geom->geometry_instance, instance_pair_buffer, idx); + ins->scenario->instance_data[ins->array_index].flags &= ~uint32_t(InstanceData::FLAG_GEOM_GI_PROBE_DIRTY); } - geometry_instances_to_render.push_back(E->get()); + frustum_cull_result.geometry_instances.push_back(geom->geometry_instance); } - scene_render->gi_probe_update(probe->probe_instance, update_lights, probe->light_instances, geometry_instances_to_render); + scene_render->gi_probe_update(probe->probe_instance, update_lights, probe->light_instances, frustum_cull_result.geometry_instances); gi_probe_update_list.remove(gi_probe); @@ -2971,7 +3145,7 @@ void RendererSceneCull::render_particle_colliders() { if (hfpc->scenario && hfpc->base_type == RS::INSTANCE_PARTICLES_COLLISION && RSG::storage->particles_collision_is_heightfield(hfpc->base)) { //update heightfield instance_cull_result.clear(); - geometry_instances_to_render.clear(); + frustum_cull_result.geometry_instances.clear(); struct CullAABB { PagedArray<Instance *> *result; @@ -2992,16 +3166,17 @@ void RendererSceneCull::render_particle_colliders() { if (!instance || !((1 << instance->base_type) & (RS::INSTANCE_GEOMETRY_MASK & (~(1 << RS::INSTANCE_PARTICLES))))) { //all but particles to avoid self collision continue; } - geometry_instances_to_render.push_back(instance); + InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); + frustum_cull_result.geometry_instances.push_back(geom->geometry_instance); } - scene_render->render_particle_collider_heightfield(hfpc->base, hfpc->transform, geometry_instances_to_render); + scene_render->render_particle_collider_heightfield(hfpc->base, hfpc->transform, frustum_cull_result.geometry_instances); } heightfield_particle_colliders_update_list.erase(heightfield_particle_colliders_update_list.front()); } } -void RendererSceneCull::_update_instance_shader_parameters_from_material(Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter> &isparams, const Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter> &existing_isparams, RID p_material) { +void RendererSceneCull::_update_instance_shader_parameters_from_material(Map<StringName, Instance::InstanceShaderParameter> &isparams, const Map<StringName, Instance::InstanceShaderParameter> &existing_isparams, RID p_material) { List<RendererStorage::InstanceShaderParam> plist; RSG::storage->material_get_instance_shader_parameters(p_material, &plist); for (List<RendererStorage::InstanceShaderParam>::Element *E = plist.front(); E; E = E->next()) { @@ -3016,7 +3191,7 @@ void RendererSceneCull::_update_instance_shader_parameters_from_material(Map<Str continue; //first one found always has priority } - RendererSceneRender::InstanceBase::InstanceShaderParameter isp; + Instance::InstanceShaderParameter isp; isp.index = E->get().index; isp.info = E->get().info; isp.default_value = E->get().default_value; @@ -3035,14 +3210,14 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { } if (p_instance->update_dependencies) { - p_instance->instance_increase_version(); + p_instance->dependency_tracker.update_begin(); if (p_instance->base.is_valid()) { - RSG::storage->base_update_dependency(p_instance->base, p_instance); + RSG::storage->base_update_dependency(p_instance->base, &p_instance->dependency_tracker); } if (p_instance->material_override.is_valid()) { - RSG::storage->material_update_dependency(p_instance->material_override, p_instance); + RSG::storage->material_update_dependency(p_instance->material_override, &p_instance->dependency_tracker); } if (p_instance->base_type == RS::INSTANCE_MESH) { @@ -3059,7 +3234,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { bool can_cast_shadows = true; bool is_animated = false; - Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter> isparams; + Map<StringName, Instance::InstanceShaderParameter> isparams; if (p_instance->cast_shadows == RS::SHADOW_CASTING_SETTING_OFF) { can_cast_shadows = false; @@ -3094,7 +3269,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat); - RSG::storage->material_update_dependency(mat, p_instance); + RSG::storage->material_update_dependency(mat, &p_instance->dependency_tracker); } } @@ -3125,7 +3300,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat); - RSG::storage->material_update_dependency(mat, p_instance); + RSG::storage->material_update_dependency(mat, &p_instance->dependency_tracker); } } @@ -3133,7 +3308,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { can_cast_shadows = false; } - RSG::storage->base_update_dependency(mesh, p_instance); + RSG::storage->base_update_dependency(mesh, &p_instance->dependency_tracker); } } else if (p_instance->base_type == RS::INSTANCE_IMMEDIATE) { RID mat = RSG::storage->immediate_get_material(p_instance->base); @@ -3151,7 +3326,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { } if (mat.is_valid()) { - RSG::storage->material_update_dependency(mat, p_instance); + RSG::storage->material_update_dependency(mat, &p_instance->dependency_tracker); } } else if (p_instance->base_type == RS::INSTANCE_PARTICLES) { @@ -3182,7 +3357,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat); - RSG::storage->material_update_dependency(mat, p_instance); + RSG::storage->material_update_dependency(mat, &p_instance->dependency_tracker); } } } @@ -3210,7 +3385,9 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { p_instance->instance_allocated_shader_parameters = (p_instance->instance_shader_parameters.size() > 0); if (p_instance->instance_allocated_shader_parameters) { p_instance->instance_allocated_shader_parameters_offset = RSG::storage->global_variables_instance_allocate(p_instance->self); - for (Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter>::Element *E = p_instance->instance_shader_parameters.front(); E; E = E->next()) { + scene_render->geometry_instance_set_instance_shader_parameters_offset(geom->geometry_instance, p_instance->instance_allocated_shader_parameters_offset); + + for (Map<StringName, Instance::InstanceShaderParameter>::Element *E = p_instance->instance_shader_parameters.front(); E; E = E->next()) { if (E->get().value.get_type() != Variant::NIL) { RSG::storage->global_variables_instance_update(p_instance->self, E->get().index, E->get().value); } @@ -3218,15 +3395,21 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { } else { RSG::storage->global_variables_instance_free(p_instance->self); p_instance->instance_allocated_shader_parameters_offset = -1; + scene_render->geometry_instance_set_instance_shader_parameters_offset(geom->geometry_instance, -1); } } } if (p_instance->skeleton.is_valid()) { - RSG::storage->skeleton_update_dependency(p_instance->skeleton, p_instance); + RSG::storage->skeleton_update_dependency(p_instance->skeleton, &p_instance->dependency_tracker); } - p_instance->clean_up_dependencies(); + p_instance->dependency_tracker.update_end(); + + if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) { + InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data); + scene_render->geometry_instance_set_surface_materials(geom->geometry_instance, p_instance->materials); + } } _instance_update_list.remove(&p_instance->update_item); @@ -3322,70 +3505,50 @@ TypedArray<Image> RendererSceneCull::bake_render_uv2(RID p_base, const Vector<RI RendererSceneCull *RendererSceneCull::singleton = nullptr; +void RendererSceneCull::set_scene_render(RendererSceneRender *p_scene_render) { + scene_render = p_scene_render; + geometry_instance_pair_mask = scene_render->geometry_instance_get_pair_mask(); +} + RendererSceneCull::RendererSceneCull() { render_pass = 1; singleton = this; - pair_volumes_to_mesh = false; instance_cull_result.set_page_pool(&instance_cull_page_pool); - mesh_instance_cull_result.set_page_pool(&rid_cull_page_pool); instance_shadow_cull_result.set_page_pool(&instance_cull_page_pool); - instance_sdfgi_cull_result.set_page_pool(&instance_cull_page_pool); - light_cull_result.set_page_pool(&instance_cull_page_pool); - geometry_instances_to_render.set_page_pool(&base_instance_cull_page_pool); - geometry_instances_to_shadow_render.set_page_pool(&base_instance_cull_page_pool); - lightmap_cull_result.set_page_pool(&base_instance_cull_page_pool); - - reflection_probe_instance_cull_result.set_page_pool(&rid_cull_page_pool); - light_instance_cull_result.set_page_pool(&rid_cull_page_pool); - gi_probe_instance_cull_result.set_page_pool(&rid_cull_page_pool); - decal_instance_cull_result.set_page_pool(&rid_cull_page_pool); - - for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) { - for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) { - cull.shadows[i].cascades[j].cull_result.set_page_pool(&base_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 (int i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) { - cull.sdfgi.region_cull_result[i].set_page_pool(&base_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); } - for (int i = 0; i < SDFGI_MAX_CASCADES; i++) { - cull.sdfgi.cascade_lights[i].set_page_pool(&rid_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()); + for (uint32_t i = 0; i < frustum_cull_result_threads.size(); i++) { + 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"); + 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 } RendererSceneCull::~RendererSceneCull() { instance_cull_result.reset(); - mesh_instance_cull_result.reset(); instance_shadow_cull_result.reset(); - instance_sdfgi_cull_result.reset(); - light_cull_result.reset(); - - geometry_instances_to_render.reset(); - geometry_instances_to_shadow_render.reset(); - lightmap_cull_result.reset(); - - reflection_probe_instance_cull_result.reset(); - light_instance_cull_result.reset(); - gi_probe_instance_cull_result.reset(); - decal_instance_cull_result.reset(); - for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) { - for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) { - cull.shadows[i].cascades[j].cull_result.reset(); - } + for (uint32_t i = 0; i < MAX_UPDATE_SHADOWS; i++) { + render_shadow_data[i].instances.reset(); } - - for (int i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) { - cull.sdfgi.region_cull_result[i].reset(); + for (uint32_t i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) { + render_sdfgi_data[i].instances.reset(); } - for (int i = 0; i < SDFGI_MAX_CASCADES; i++) { - cull.sdfgi.cascade_lights[i].reset(); + frustum_cull_result.reset(); + for (uint32_t i = 0; i < frustum_cull_result_threads.size(); i++) { + frustum_cull_result_threads[i].reset(); } + frustum_cull_result_threads.clear(); } diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h index 85b4c53c59..d6d730af15 100644 --- a/servers/rendering/renderer_scene_cull.h +++ b/servers/rendering/renderer_scene_cull.h @@ -53,7 +53,9 @@ public: enum { SDFGI_MAX_CASCADES = 8, - SDFGI_MAX_REGIONS_PER_CASCADE = 3 + SDFGI_MAX_REGIONS_PER_CASCADE = 3, + MAX_INSTANCE_PAIRS = 32, + MAX_UPDATE_SHADOWS = 512 }; uint64_t render_pass; @@ -249,7 +251,10 @@ public: uint32_t flags = 0; uint32_t layer_mask = 0; //for fast layer-mask discard RID base_rid; - RID instance_data_rid; + union { + uint64_t instance_data_rid; + RendererSceneRender::GeometryInstance *instance_geometry; + }; Instance *instance = nullptr; }; @@ -296,7 +301,7 @@ public: static void _instance_pair(Instance *p_A, Instance *p_B); static void _instance_unpair(Instance *p_A, Instance *p_B); - static void _instance_update_mesh_instance(Instance *p_instance); + void _instance_update_mesh_instance(Instance *p_instance); virtual RID scenario_create(); @@ -325,7 +330,55 @@ public: virtual ~InstanceBaseData() {} }; - struct Instance : RendererSceneRender::InstanceBase { + struct Instance { + RS::InstanceType base_type; + RID base; + + RID skeleton; + RID material_override; + + RID mesh_instance; //only used for meshes and when skeleton/blendshapes exist + + Transform transform; + + float lod_bias; + + Vector<RID> materials; + + RS::ShadowCastingSetting cast_shadows; + + uint32_t layer_mask; + //fit in 32 bits + bool mirror : 8; + bool receive_shadows : 8; + bool visible : 8; + bool baked_light : 2; //this flag is only to know if it actually did use baked light + bool dynamic_gi : 2; //same above for dynamic objects + bool redraw_if_visible : 4; + + Instance *lightmap; + Rect2 lightmap_uv_scale; + int lightmap_slice_index; + uint32_t lightmap_cull_index; + Vector<Color> lightmap_sh; //spherical harmonic + + AABB aabb; + AABB transformed_aabb; + AABB prev_transformed_aabb; + + struct InstanceShaderParameter { + int32_t index = -1; + Variant value; + Variant default_value; + PropertyInfo info; + }; + + Map<StringName, InstanceShaderParameter> instance_shader_parameters; + bool instance_allocated_shader_parameters = false; + int32_t instance_allocated_shader_parameters_offset = -1; + + // + RID self; //scenario stuff DynamicBVH::ID indexer_id; @@ -360,23 +413,61 @@ public: SelfList<InstancePair>::List pairs; uint64_t pair_check; - virtual void dependency_deleted(RID p_dependency) { - if (p_dependency == base) { - singleton->instance_set_base(self, RID()); - } else if (p_dependency == skeleton) { - singleton->instance_attach_skeleton(self, RID()); - } else { - singleton->_instance_queue_update(this, false, true); + RendererStorage::DependencyTracker dependency_tracker; + + static void dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *tracker) { + Instance *instance = (Instance *)tracker->userdata; + switch (p_notification) { + case RendererStorage::DEPENDENCY_CHANGED_SKELETON_DATA: + case RendererStorage::DEPENDENCY_CHANGED_AABB: { + singleton->_instance_queue_update(instance, true, false); + + } break; + case RendererStorage::DEPENDENCY_CHANGED_MATERIAL: { + singleton->_instance_queue_update(instance, false, true); + } break; + case RendererStorage::DEPENDENCY_CHANGED_MESH: + case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH: + case RendererStorage::DEPENDENCY_CHANGED_DECAL: + case RendererStorage::DEPENDENCY_CHANGED_LIGHT: + case RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE: { + singleton->_instance_queue_update(instance, true, true); + } break; + case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: + case RendererStorage::DEPENDENCY_CHANGED_SKELETON_BONES: { + //ignored + } break; } } - virtual void dependency_changed(bool p_aabb, bool p_dependencies) { - singleton->_instance_queue_update(this, p_aabb, p_dependencies); + static void dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *tracker) { + Instance *instance = (Instance *)tracker->userdata; + + if (p_dependency == instance->base) { + singleton->instance_set_base(instance->self, RID()); + } else if (p_dependency == instance->skeleton) { + singleton->instance_attach_skeleton(instance->self, RID()); + } else { + singleton->_instance_queue_update(instance, false, true); + } } Instance() : scenario_item(this), update_item(this) { + base_type = RS::INSTANCE_NONE; + cast_shadows = RS::SHADOW_CASTING_SETTING_ON; + receive_shadows = true; + visible = true; + layer_mask = 1; + baked_light = false; + dynamic_gi = false; + redraw_if_visible = false; + lightmap_slice_index = 0; + lightmap = nullptr; + lightmap_cull_index = 0; + lod_bias = 1.0; + scenario = nullptr; update_aabb = false; @@ -399,6 +490,10 @@ public: pair_check = 0; array_index = -1; + + dependency_tracker.userdata = this; + dependency_tracker.changed_callback = dependency_changed; + dependency_tracker.deleted_callback = dependency_deleted; } ~Instance() { @@ -415,6 +510,7 @@ public: void _instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_dependencies = false); struct InstanceGeometryData : public InstanceBaseData { + RendererSceneRender::GeometryInstance *geometry_instance = nullptr; Set<Instance *> lights; bool can_cast_shadows; bool material_is_animated; @@ -458,6 +554,10 @@ public: SelfList<InstanceReflectionProbeData>::List reflection_probe_render_list; + struct InstanceParticlesCollisionData : public InstanceBaseData { + RID instance; + }; + struct InstanceLightData : public InstanceBaseData { RID instance; uint64_t last_version; @@ -523,6 +623,7 @@ public: SelfList<InstanceGIProbeData>::List gi_probe_update_list; struct InstanceLightmapData : public InstanceBaseData { + RID instance; Set<Instance *> geometries; Set<Instance *> users; @@ -588,38 +689,144 @@ public: } }; - struct CullResult { - PagedArray<Instance *> *result; - _FORCE_INLINE_ bool operator()(void *p_data) { - Instance *p_instance = (Instance *)p_data; - result->push_back(p_instance); - return false; - } - }; - Set<Instance *> heightfield_particle_colliders_update_list; PagedArrayPool<Instance *> instance_cull_page_pool; - PagedArrayPool<RendererSceneRender::InstanceBase *> base_instance_cull_page_pool; + PagedArrayPool<RendererSceneRender::GeometryInstance *> geometry_instance_cull_page_pool; PagedArrayPool<RID> rid_cull_page_pool; PagedArray<Instance *> instance_cull_result; - PagedArray<RID> mesh_instance_cull_result; - PagedArray<RendererSceneRender::InstanceBase *> geometry_instances_to_render; PagedArray<Instance *> instance_shadow_cull_result; - PagedArray<RendererSceneRender::InstanceBase *> geometry_instances_to_shadow_render; - PagedArray<Instance *> instance_sdfgi_cull_result; - PagedArray<Instance *> light_cull_result; - PagedArray<RendererSceneRender::InstanceBase *> lightmap_cull_result; - PagedArray<RID> reflection_probe_instance_cull_result; - PagedArray<RID> light_instance_cull_result; - PagedArray<RID> gi_probe_instance_cull_result; - PagedArray<RID> decal_instance_cull_result; + struct FrustumCullResult { + PagedArray<RendererSceneRender::GeometryInstance *> geometry_instances; + PagedArray<Instance *> lights; + PagedArray<RID> light_instances; + PagedArray<RID> lightmaps; + PagedArray<RID> reflections; + PagedArray<RID> decals; + PagedArray<RID> gi_probes; + PagedArray<RID> mesh_instances; + + struct DirectionalShadow { + PagedArray<RendererSceneRender::GeometryInstance *> cascade_geometry_instances[RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES]; + } directional_shadows[RendererSceneRender::MAX_DIRECTIONAL_LIGHTS]; + + PagedArray<RendererSceneRender::GeometryInstance *> sdfgi_region_geometry_instances[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE]; + PagedArray<RID> sdfgi_cascade_lights[SDFGI_MAX_CASCADES]; + + void clear() { + geometry_instances.clear(); + lights.clear(); + light_instances.clear(); + lightmaps.clear(); + reflections.clear(); + decals.clear(); + gi_probes.clear(); + mesh_instances.clear(); + for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) { + for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) { + directional_shadows[i].cascade_geometry_instances[j].clear(); + } + } + + for (int i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) { + sdfgi_region_geometry_instances[i].clear(); + } + + for (int i = 0; i < SDFGI_MAX_CASCADES; i++) { + sdfgi_cascade_lights[i].clear(); + } + } + + void reset() { + geometry_instances.reset(); + lights.reset(); + light_instances.reset(); + lightmaps.reset(); + reflections.reset(); + decals.reset(); + gi_probes.reset(); + mesh_instances.reset(); + for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) { + for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) { + directional_shadows[i].cascade_geometry_instances[j].reset(); + } + } + + for (int i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) { + sdfgi_region_geometry_instances[i].reset(); + } + + for (int i = 0; i < SDFGI_MAX_CASCADES; i++) { + sdfgi_cascade_lights[i].reset(); + } + } + + void append_from(FrustumCullResult &p_cull_result) { + geometry_instances.merge_unordered(p_cull_result.geometry_instances); + lights.merge_unordered(p_cull_result.lights); + light_instances.merge_unordered(p_cull_result.light_instances); + lightmaps.merge_unordered(p_cull_result.lightmaps); + reflections.merge_unordered(p_cull_result.reflections); + decals.merge_unordered(p_cull_result.decals); + gi_probes.merge_unordered(p_cull_result.gi_probes); + mesh_instances.merge_unordered(p_cull_result.mesh_instances); + + for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) { + for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) { + directional_shadows[i].cascade_geometry_instances[j].merge_unordered(p_cull_result.directional_shadows[i].cascade_geometry_instances[j]); + } + } + + for (int i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) { + sdfgi_region_geometry_instances[i].merge_unordered(p_cull_result.sdfgi_region_geometry_instances[i]); + } + + for (int i = 0; i < SDFGI_MAX_CASCADES; i++) { + sdfgi_cascade_lights[i].merge_unordered(p_cull_result.sdfgi_cascade_lights[i]); + } + } + + void init(PagedArrayPool<RID> *p_rid_pool, PagedArrayPool<RendererSceneRender::GeometryInstance *> *p_geometry_instance_pool, PagedArrayPool<Instance *> *p_instance_pool) { + geometry_instances.set_page_pool(p_geometry_instance_pool); + light_instances.set_page_pool(p_rid_pool); + lights.set_page_pool(p_instance_pool); + 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++) { + directional_shadows[i].cascade_geometry_instances[j].set_page_pool(p_geometry_instance_pool); + } + } + + for (int i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) { + sdfgi_region_geometry_instances[i].set_page_pool(p_geometry_instance_pool); + } + + for (int i = 0; i < SDFGI_MAX_CASCADES; i++) { + sdfgi_cascade_lights[i].set_page_pool(p_rid_pool); + } + } + }; + + 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; - bool pair_volumes_to_mesh; // used in traditional forward, unnecesary on clustered + uint32_t geometry_instance_pair_mask; // used in traditional forward, unnecesary on clustered virtual RID instance_create(); @@ -653,7 +860,7 @@ public: virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index); virtual void instance_geometry_set_lod_bias(RID p_instance, float p_lod_bias); - void _update_instance_shader_parameters_from_material(Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter> &isparams, const Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter> &existing_isparams, RID p_material); + void _update_instance_shader_parameters_from_material(Map<StringName, Instance::InstanceShaderParameter> &isparams, const Map<StringName, Instance::InstanceShaderParameter> &existing_isparams, RID p_material); virtual void instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value); virtual void instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const; @@ -687,8 +894,6 @@ public: real_t range_begin; Vector2 uv_scale; - PagedArray<RendererSceneRender::InstanceBase *> cull_result; - } cascades[RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES]; //max 4 cascades uint32_t cascade_count; @@ -698,12 +903,10 @@ public: struct SDFGI { //have arrays here because SDFGI functions expects this, plus regions can have areas - PagedArray<RendererSceneRender::InstanceBase *> region_cull_result[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE]; AABB region_aabb[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE]; //max 3 regions per cascade uint32_t region_cascade[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE]; //max 3 regions per cascade uint32_t region_count = 0; - PagedArray<RID> cascade_lights[SDFGI_MAX_CASCADES]; uint32_t cascade_light_index[SDFGI_MAX_CASCADES]; uint32_t cascade_light_count = 0; @@ -714,9 +917,20 @@ public: Frustum frustum; } cull; + struct FrustumCullData { + Cull *cull; + Scenario *scenario; + RID shadow_atlas; + Transform cam_transform; + uint32_t visible_layers; + Instance *render_reflection_probe; + }; + + void _frustum_cull_threaded(uint32_t p_thread, FrustumCullData *cull_data); + 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); @@ -738,7 +952,7 @@ 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 */ @@ -777,16 +991,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) 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) @@ -816,10 +1029,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) @@ -828,6 +1042,8 @@ public: bool free(RID p_rid); + void set_scene_render(RendererSceneRender *p_scene_render); + RendererSceneCull(); virtual ~RendererSceneCull(); }; diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h index 805d3dcfce..72fcdd3758 100644 --- a/servers/rendering/renderer_scene_render.h +++ b/servers/rendering/renderer_scene_render.h @@ -41,27 +41,52 @@ public: MAX_DIRECTIONAL_LIGHTS = 8, MAX_DIRECTIONAL_LIGHT_CASCADES = 4 }; + + struct GeometryInstance { + virtual ~GeometryInstance() {} + }; + + virtual GeometryInstance *geometry_instance_create(RID p_base) = 0; + virtual void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) = 0; + virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) = 0; + virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_material) = 0; + virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) = 0; + virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) = 0; + virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) = 0; + virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) = 0; + virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) = 0; + virtual void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) = 0; + virtual 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) = 0; + virtual void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) = 0; + virtual void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) = 0; + virtual void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) = 0; + + virtual uint32_t geometry_instance_get_pair_mask() = 0; + virtual void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) = 0; + virtual void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) = 0; + virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) = 0; + virtual void geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count) = 0; + + virtual void geometry_instance_free(GeometryInstance *p_geometry_instance) = 0; + /* SHADOW ATLAS API */ 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_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; /* SDFGI UPDATE */ - struct InstanceBase; - virtual void sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) = 0; 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 */ @@ -92,12 +117,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; @@ -110,6 +132,7 @@ public: 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; @@ -134,83 +157,6 @@ public: virtual void shadows_quality_set(RS::ShadowQuality p_quality) = 0; virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality) = 0; - struct InstanceBase : public RendererStorage::InstanceBaseDependency { - RS::InstanceType base_type; - RID base; - - RID skeleton; - RID material_override; - - RID mesh_instance; //only used for meshes and when skeleton/blendshapes exist - - Transform transform; - - float lod_bias; - - int depth_layer; - uint32_t layer_mask; - - //RID sampled_light; - - Vector<RID> materials; - Vector<RID> light_instances; - Vector<RID> reflection_probe_instances; - Vector<RID> gi_probe_instances; - - RS::ShadowCastingSetting cast_shadows; - - //fit in 32 bits - bool mirror : 8; - bool receive_shadows : 8; - bool visible : 8; - bool baked_light : 2; //this flag is only to know if it actually did use baked light - bool dynamic_gi : 2; //this flag is only to know if it actually did use baked light - bool redraw_if_visible : 4; - - float depth; //used for sorting - - InstanceBase *lightmap; - Rect2 lightmap_uv_scale; - int lightmap_slice_index; - uint32_t lightmap_cull_index; - Vector<Color> lightmap_sh; //spherical harmonic - - AABB aabb; - AABB transformed_aabb; - AABB prev_transformed_aabb; - - struct InstanceShaderParameter { - int32_t index = -1; - Variant value; - Variant default_value; - PropertyInfo info; - }; - - Map<StringName, InstanceShaderParameter> instance_shader_parameters; - bool instance_allocated_shader_parameters = false; - int32_t instance_allocated_shader_parameters_offset = -1; - - InstanceBase() { - base_type = RS::INSTANCE_NONE; - cast_shadows = RS::SHADOW_CASTING_SETTING_ON; - receive_shadows = true; - visible = true; - depth_layer = 0; - layer_mask = 1; - instance_version = 0; - baked_light = false; - dynamic_gi = false; - redraw_if_visible = false; - lightmap_slice_index = 0; - lightmap = nullptr; - lightmap_cull_index = 0; - lod_bias = 1.0; - } - - virtual ~InstanceBase() { - } - }; - virtual RID light_instance_create(RID p_light) = 0; virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform) = 0; virtual void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) = 0; @@ -235,20 +181,42 @@ public: virtual RID decal_instance_create(RID p_decal) = 0; virtual void decal_instance_set_transform(RID p_decal, const Transform &p_transform) = 0; + virtual RID lightmap_instance_create(RID p_lightmap) = 0; + virtual void lightmap_instance_set_transform(RID p_lightmap, const Transform &p_transform) = 0; + virtual RID gi_probe_instance_create(RID p_gi_probe) = 0; virtual void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) = 0; virtual bool gi_probe_needs_update(RID p_probe) const = 0; - virtual void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::InstanceBase *> &p_dynamic_objects) = 0; + virtual void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<GeometryInstance *> &p_dynamic_objects) = 0; 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<InstanceBase *> &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<InstanceBase *> &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<InstanceBase *> &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<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; - virtual void render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<InstanceBase *> &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<InstanceBase *> &p_instances) = 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_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; virtual void set_time(double p_time, double p_step) = 0; @@ -256,6 +224,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.cpp b/servers/rendering/renderer_storage.cpp index 2edf62df56..a402ecc668 100644 --- a/servers/rendering/renderer_storage.cpp +++ b/servers/rendering/renderer_storage.cpp @@ -32,28 +32,31 @@ RendererStorage *RendererStorage::base_singleton = nullptr; -void RendererStorage::InstanceDependency::instance_notify_changed(bool p_aabb, bool p_dependencies) { - for (Map<InstanceBaseDependency *, uint32_t>::Element *E = instances.front(); E; E = E->next()) { - E->key()->dependency_changed(p_aabb, p_dependencies); +void RendererStorage::Dependency::changed_notify(DependencyChangedNotification p_notification) { + for (Map<DependencyTracker *, uint32_t>::Element *E = instances.front(); E; E = E->next()) { + if (E->key()->changed_callback) { + E->key()->changed_callback(p_notification, E->key()); + } } } -void RendererStorage::InstanceDependency::instance_notify_deleted(RID p_deleted) { - for (Map<InstanceBaseDependency *, uint32_t>::Element *E = instances.front(); E; E = E->next()) { - E->key()->dependency_deleted(p_deleted); +void RendererStorage::Dependency::deleted_notify(const RID &p_rid) { + for (Map<DependencyTracker *, uint32_t>::Element *E = instances.front(); E; E = E->next()) { + if (E->key()->deleted_callback) { + E->key()->deleted_callback(p_rid, E->key()); + } } - for (Map<InstanceBaseDependency *, uint32_t>::Element *E = instances.front(); E; E = E->next()) { + for (Map<DependencyTracker *, uint32_t>::Element *E = instances.front(); E; E = E->next()) { E->key()->dependencies.erase(this); } - instances.clear(); } -RendererStorage::InstanceDependency::~InstanceDependency() { +RendererStorage::Dependency::~Dependency() { #ifdef DEBUG_ENABLED if (instances.size()) { WARN_PRINT("Leaked instance dependency: Bug - did not call instance_notify_deleted when freeing."); - for (Map<InstanceBaseDependency *, uint32_t>::Element *E = instances.front(); E; E = E->next()) { + for (Map<DependencyTracker *, uint32_t>::Element *E = instances.front(); E; E = E->next()) { E->key()->dependencies.erase(this); } } diff --git a/servers/rendering/renderer_storage.h b/servers/rendering/renderer_storage.h index 835bf32863..f015b50eee 100644 --- a/servers/rendering/renderer_storage.h +++ b/servers/rendering/renderer_storage.h @@ -37,43 +37,59 @@ class RendererStorage { Color default_clear_color; public: - struct InstanceBaseDependency; + enum DependencyChangedNotification { + DEPENDENCY_CHANGED_AABB, + DEPENDENCY_CHANGED_MATERIAL, + DEPENDENCY_CHANGED_MESH, + DEPENDENCY_CHANGED_MULTIMESH, + DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES, + DEPENDENCY_CHANGED_DECAL, + DEPENDENCY_CHANGED_SKELETON_DATA, + DEPENDENCY_CHANGED_SKELETON_BONES, + DEPENDENCY_CHANGED_LIGHT, + DEPENDENCY_CHANGED_REFLECTION_PROBE, + }; + + struct DependencyTracker; - struct InstanceDependency { - void instance_notify_changed(bool p_aabb, bool p_dependencies); - void instance_notify_deleted(RID p_deleted); +protected: + struct Dependency { + void changed_notify(DependencyChangedNotification p_notification); + void deleted_notify(const RID &p_rid); - ~InstanceDependency(); + ~Dependency(); private: - friend struct InstanceBaseDependency; - Map<InstanceBaseDependency *, uint32_t> instances; + friend struct DependencyTracker; + Map<DependencyTracker *, uint32_t> instances; }; - struct InstanceBaseDependency { - uint32_t instance_version; - Set<InstanceDependency *> dependencies; +public: + struct DependencyTracker { + void *userdata = nullptr; + typedef void (*ChangedCallback)(DependencyChangedNotification, DependencyTracker *); + typedef void (*DeletedCallback)(const RID &, DependencyTracker *); - virtual void dependency_deleted(RID p_dependency) {} - virtual void dependency_changed(bool p_aabb, bool p_dependencies) {} + ChangedCallback changed_callback = nullptr; + DeletedCallback deleted_callback = nullptr; - void instance_increase_version() { + void update_begin() { // call before updating dependencies instance_version++; } - void update_dependency(InstanceDependency *p_dependency) { + void update_dependency(Dependency *p_dependency) { //called internally, can't be used directly, use update functions in Storage dependencies.insert(p_dependency); p_dependency->instances[this] = instance_version; } - void clean_up_dependencies() { - List<Pair<InstanceDependency *, Map<InstanceBaseDependency *, uint32_t>::Element *>> to_clean_up; - for (Set<InstanceDependency *>::Element *E = dependencies.front(); E; E = E->next()) { - InstanceDependency *dep = E->get(); - Map<InstanceBaseDependency *, uint32_t>::Element *F = dep->instances.find(this); + void update_end() { //call after updating dependencies + List<Pair<Dependency *, Map<DependencyTracker *, uint32_t>::Element *>> to_clean_up; + for (Set<Dependency *>::Element *E = dependencies.front(); E; E = E->next()) { + Dependency *dep = E->get(); + Map<DependencyTracker *, uint32_t>::Element *F = dep->instances.find(this); ERR_CONTINUE(!F); if (F->get() != instance_version) { - Pair<InstanceDependency *, Map<InstanceBaseDependency *, uint32_t>::Element *> p; + Pair<Dependency *, Map<DependencyTracker *, uint32_t>::Element *> p; p.first = dep; p.second = F; to_clean_up.push_back(p); @@ -82,19 +98,25 @@ 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(); } } - void clear_dependencies() { - for (Set<InstanceDependency *>::Element *E = dependencies.front(); E; E = E->next()) { - InstanceDependency *dep = E->get(); + void clear() { // clear all dependencies + for (Set<Dependency *>::Element *E = dependencies.front(); E; E = E->next()) { + Dependency *dep = E->get(); dep->instances.erase(this); } dependencies.clear(); } - virtual ~InstanceBaseDependency() { clear_dependencies(); } + ~DependencyTracker() { clear(); } + + private: + friend struct Dependency; + uint32_t instance_version = 0; + Set<Dependency *> dependencies; }; /* TEXTURE API */ @@ -158,6 +180,8 @@ public: virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name) const = 0; virtual Variant shader_get_param_default(RID p_material, const StringName &p_param) const = 0; + virtual RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const = 0; + /* COMMON MATERIAL API */ virtual RID material_create() = 0; @@ -181,7 +205,7 @@ public: virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) = 0; - virtual void material_update_dependency(RID p_material, InstanceBaseDependency *p_instance) = 0; + virtual void material_update_dependency(RID p_material, DependencyTracker *p_instance) = 0; /* MESH API */ @@ -211,6 +235,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; @@ -349,8 +375,8 @@ public: virtual bool reflection_probe_renders_shadows(RID p_probe) const = 0; virtual float reflection_probe_get_lod_threshold(RID p_probe) const = 0; - virtual void base_update_dependency(RID p_base, InstanceBaseDependency *p_instance) = 0; - virtual void skeleton_update_dependency(RID p_base, InstanceBaseDependency *p_instance) = 0; + virtual void base_update_dependency(RID p_base, DependencyTracker *p_instance) = 0; + virtual void skeleton_update_dependency(RID p_base, DependencyTracker *p_instance) = 0; /* DECAL API */ @@ -474,8 +500,8 @@ public: virtual void particles_set_view_axis(RID p_particles, const Vector3 &p_axis) = 0; - virtual void particles_add_collision(RID p_particles, InstanceBaseDependency *p_instance) = 0; - virtual void particles_remove_collision(RID p_particles, InstanceBaseDependency *p_instance) = 0; + virtual void particles_add_collision(RID p_particles, RID p_particles_collision_instance) = 0; + virtual void particles_remove_collision(RID p_particles, RID p_particles_collision_instance) = 0; virtual void update_particles() = 0; @@ -496,6 +522,11 @@ public: virtual bool particles_collision_is_heightfield(RID p_particles_collision) const = 0; virtual RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const = 0; + //used from 2D and 3D + virtual RID particles_collision_instance_create(RID p_collision) = 0; + virtual void particles_collision_instance_set_transform(RID p_collision_instance, const Transform &p_transform) = 0; + virtual void particles_collision_instance_set_active(RID p_collision_instance, bool p_active) = 0; + /* GLOBAL VARIABLES */ virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) = 0; diff --git a/modules/camera_iphone/camera_module.cpp b/servers/rendering/renderer_thread_pool.cpp index 7ea035892e..98050dd508 100644 --- a/modules/camera_iphone/camera_module.cpp +++ b/servers/rendering/renderer_thread_pool.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* camera_module.cpp */ +/* renderer_thread_pool.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,13 +28,15 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "camera_module.h" +#include "renderer_thread_pool.h" -#include "camera_ios.h" +RendererThreadPool *RendererThreadPool::singleton = nullptr; -void register_camera_types() { - CameraServer::make_default<CameraIOS>(); +RendererThreadPool::RendererThreadPool() { + singleton = this; + thread_work_pool.init(); } -void unregister_camera_types() { +RendererThreadPool::~RendererThreadPool() { + thread_work_pool.finish(); } diff --git a/modules/camera_iphone/camera_ios.h b/servers/rendering/renderer_thread_pool.h index 0566457a0f..ae25415a0d 100644 --- a/modules/camera_iphone/camera_ios.h +++ b/servers/rendering/renderer_thread_pool.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* camera_ios.h */ +/* renderer_thread_pool.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,18 +28,18 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef CAMERAIOS_H -#define CAMERAIOS_H +#ifndef RENDERERTHREADPOOL_H +#define RENDERERTHREADPOOL_H -#include "servers/camera_server.h" +#include "core/templates/thread_work_pool.h" -class CameraIOS : public CameraServer { -private: +class RendererThreadPool { public: - CameraIOS(); - ~CameraIOS(); + ThreadWorkPool thread_work_pool; - void update_feeds(); + static RendererThreadPool *singleton; + RendererThreadPool(); + ~RendererThreadPool(); }; -#endif /* CAMERAIOS_H */ +#endif // RENDERERTHREADPOOL_H diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp index 9956e4050b..d52da5b331 100644 --- a/servers/rendering/renderer_viewport.cpp +++ b/servers/rendering/renderer_viewport.cpp @@ -831,13 +831,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) { diff --git a/servers/rendering/renderer_viewport.h b/servers/rendering/renderer_viewport.h index c3ff52a836..979cbb095b 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; @@ -217,7 +218,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); diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index 73c86a0a1d..4b0eafe369 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); @@ -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 fb5db8de60..360b333454 100644 --- a/servers/rendering/rendering_server_default.cpp +++ b/servers/rendering/rendering_server_default.cpp @@ -162,6 +162,51 @@ 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 { @@ -232,6 +277,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(); @@ -267,7 +317,7 @@ RenderingServerDefault::RenderingServerDefault() { RSG::rasterizer = RendererCompositor::create(); RSG::storage = RSG::rasterizer->get_storage(); RSG::canvas_render = RSG::rasterizer->get_canvas(); - sr->scene_render = RSG::rasterizer->get_scene(); + sr->set_scene_render(RSG::rasterizer->get_scene()); frame_profile_frame = 0; diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index 3ccb5c4bbc..823d28c669 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -32,6 +32,7 @@ #define RENDERING_SERVER_DEFAULT_H #include "core/math/octree.h" +#include "core/templates/ordered_hash_map.h" #include "renderer_canvas_cull.h" #include "renderer_scene_cull.h" #include "renderer_viewport.h" @@ -74,6 +75,12 @@ 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; + public: //if editor is redrawing when it shouldn't, enable this and put a breakpoint in _changes_changed() //#define DEBUG_CHANGES @@ -219,6 +226,8 @@ public: BIND2RC(RID, shader_get_default_texture_param, RID, const StringName &) BIND2RC(Variant, shader_get_param_default, RID, const StringName &) + BIND1RC(ShaderNativeSourceCode, shader_get_native_source_code, RID) + /* COMMON MATERIAL API */ BIND0R(RID, material_create) @@ -265,6 +274,8 @@ public: BIND2(mesh_set_custom_aabb, RID, const AABB &) BIND1RC(AABB, mesh_get_custom_aabb, RID) + BIND2(mesh_set_shadow_mesh, RID, RID) + BIND1(mesh_clear, RID) /* MULTIMESH API */ @@ -542,7 +553,7 @@ public: 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_shadow_atlas_size, RID, int, bool) 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) @@ -563,7 +574,7 @@ public: //from now on, calls forwarded to this singleton #define BINDBASE RSG::scene - BIND1(directional_shadow_atlas_set_size, int) + BIND2(directional_shadow_atlas_set_size, int, bool) BIND1(gi_probe_set_quality, GIProbeQuality) /* SKY API */ @@ -604,16 +615,15 @@ public: BIND7(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) + BIND10(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) 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) + BIND1(environment_set_sdfgi_frames_to_update_light, EnvironmentSDFGIFramesToUpdateLight) BIND3R(Ref<Image>, environment_bake_panorama, RID, bool, const Size2i &) @@ -686,6 +696,8 @@ public: BIND3R(TypedArray<Image>, bake_render_uv2, RID, const Vector<RID> &, const Size2i &) + BIND1(gi_set_use_half_resolution, bool) + #undef BINDBASE //from now on, calls forwarded to this singleton #define BINDBASE RSG::canvas @@ -863,6 +875,8 @@ public: virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir); + virtual void set_print_gpu_profile(bool p_enable); + RenderingServerDefault(); ~RenderingServerDefault(); diff --git a/servers/rendering/rendering_server_wrap_mt.cpp b/servers/rendering/rendering_server_wrap_mt.cpp index 3572c4dc78..9b8d35e5b3 100644 --- a/servers/rendering/rendering_server_wrap_mt.cpp +++ b/servers/rendering/rendering_server_wrap_mt.cpp @@ -97,7 +97,7 @@ void RenderingServerWrapMT::init() { print_verbose("RenderingServerWrapMT: Creating render thread"); DisplayServer::get_singleton()->release_rendering_thread(); if (create_thread) { - thread = Thread::create(_thread_callback, this); + thread.start(_thread_callback, this); print_verbose("RenderingServerWrapMT: Starting render thread"); } while (!draw_thread_up) { @@ -136,12 +136,9 @@ void RenderingServerWrapMT::finish() { canvas_light_occluder_free_cached_ids(); canvas_occluder_polygon_free_cached_ids(); - if (thread) { + if (create_thread) { command_queue.push(this, &RenderingServerWrapMT::thread_exit); - Thread::wait_to_finish(thread); - memdelete(thread); - - thread = nullptr; + thread.wait_to_finish(); } else { rendering_server->finish(); } @@ -160,7 +157,6 @@ RenderingServerWrapMT::RenderingServerWrapMT(RenderingServer *p_contained, bool 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"); diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h index 29ee846f31..81e202780e 100644 --- a/servers/rendering/rendering_server_wrap_mt.h +++ b/servers/rendering/rendering_server_wrap_mt.h @@ -46,7 +46,7 @@ class RenderingServerWrapMT : public RenderingServer { Thread::ID server_thread; volatile bool exit; - Thread *thread; + Thread thread; volatile bool draw_thread_up; bool create_thread; @@ -129,6 +129,8 @@ public: 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) @@ -170,6 +172,7 @@ public: FUNC2(mesh_set_custom_aabb, RID, const AABB &) FUNC1RC(AABB, mesh_get_custom_aabb, RID) + FUNC2(mesh_set_shadow_mesh, RID, RID) FUNC1(mesh_clear, RID) /* MULTIMESH API */ @@ -443,7 +446,7 @@ public: 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_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) @@ -468,7 +471,7 @@ public: return rendering_server->viewport_get_measured_render_time_gpu(p_viewport); } - FUNC1(directional_shadow_atlas_set_size, int) + FUNC2(directional_shadow_atlas_set_size, int, bool) /* SKY API */ @@ -505,6 +508,7 @@ public: 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) + FUNC1(environment_set_sdfgi_frames_to_update_light, EnvironmentSDFGIFramesToUpdateLight) FUNC11(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, EnvironmentGlowBlendMode, float, float, float) FUNC1(environment_glow_set_use_bicubic_upscale, bool) @@ -516,12 +520,10 @@ public: 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) + FUNC10(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, bool, float) 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 &) @@ -742,6 +744,8 @@ public: return rendering_server->get_video_adapter_vendor(); } + FUNC1(gi_set_use_half_resolution, bool) + FUNC4(set_boot_image, const Ref<Image> &, const Color &, bool, bool) FUNC1(set_default_clear_color, const Color &) @@ -784,6 +788,10 @@ public: rendering_server->sdfgi_set_debug_probe_select(p_position, p_dir); } + virtual void set_print_gpu_profile(bool p_enable) { + rendering_server->set_print_gpu_profile(p_enable); + } + RenderingServerWrapMT(RenderingServer *p_contained, bool p_create_thread); ~RenderingServerWrapMT(); diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 0cb9220bb3..e6415c0258 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -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(); } @@ -6305,7 +6305,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; 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 758a9a34cd..41c88aa3be 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); @@ -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); @@ -2253,6 +2255,8 @@ void RenderingServer::set_render_loop_enabled(bool p_enabled) { RenderingServer::RenderingServer() { //ERR_FAIL_COND(singleton); + + thread_pool = memnew(RendererThreadPool); singleton = this; GLOBAL_DEF_RST("rendering/vram_compression/import_bptc", false); @@ -2270,6 +2274,7 @@ RenderingServer::RenderingServer() { 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/directional_shadow/16_bits", true); GLOBAL_DEF("rendering/quality/shadows/soft_shadow_quality", 2); GLOBAL_DEF("rendering/quality/shadows/soft_shadow_quality.mobile", 0); @@ -2280,18 +2285,6 @@ RenderingServer::RenderingServer() { 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); @@ -2302,6 +2295,8 @@ RenderingServer::RenderingServer() { GLOBAL_DEF("rendering/quality/reflection_atlas/reflection_size.mobile", 128); GLOBAL_DEF("rendering/quality/reflection_atlas/reflection_count", 64); + GLOBAL_DEF("rendering/quality/gi/use_half_resolution", false); + 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)")); @@ -2365,26 +2360,32 @@ RenderingServer::RenderingServer() { 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); + GLOBAL_DEF("rendering/sdfgi/probe_ray_count", 1); 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); + GLOBAL_DEF("rendering/sdfgi/frames_to_converge", 4); 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/sdfgi/frames_to_update_lights", 2); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/sdfgi/frames_to_update_lights", PropertyInfo(Variant::INT, "rendering/sdfgi/frames_to_update_lights", PROPERTY_HINT_ENUM, "1 (Slower),2,4,8,16 (Faster)")); 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); + GLOBAL_DEF("rendering/volumetric_fog/use_filter", 1); 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/cluster_builder/max_clustered_elements", 512); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/cluster_builder/max_clustered_elements", PropertyInfo(Variant::FLOAT, "rendering/cluster_builder/max_clustered_elements", PROPERTY_HINT_RANGE, "32,8192,1")); } RenderingServer::~RenderingServer() { + memdelete(thread_pool); singleton = nullptr; } diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 7db2924612..5defa1f667 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -39,6 +39,7 @@ #include "core/variant/typed_array.h" #include "core/variant/variant.h" #include "servers/display_server.h" +#include "servers/rendering/renderer_thread_pool.h" #include "servers/rendering/rendering_device.h" #include "servers/rendering/shader_language.h" @@ -52,6 +53,8 @@ class RenderingServer : public Object { Array _get_array_from_surface(uint32_t p_format, Vector<uint8_t> p_vertex_data, Vector<uint8_t> p_attrib_data, Vector<uint8_t> p_skin_data, int p_vertex_len, Vector<uint8_t> p_index_data, int p_index_len) const; + RendererThreadPool *thread_pool = nullptr; + protected: RID _make_test_cube(); void _free_internal_rids(); @@ -176,6 +179,19 @@ public: virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture) = 0; virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name) const = 0; + struct ShaderNativeSourceCode { + struct Version { + struct Stage { + String name; + String code; + }; + Vector<Stage> stages; + }; + Vector<Version> versions; + }; + + virtual ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const = 0; + /* COMMON MATERIAL API */ enum { @@ -338,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 */ @@ -782,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 { @@ -840,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; @@ -849,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 */ @@ -967,6 +988,7 @@ public: 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; enum EnvironmentSDFGIRayCount { + ENV_SDFGI_RAY_COUNT_4, ENV_SDFGI_RAY_COUNT_8, ENV_SDFGI_RAY_COUNT_16, ENV_SDFGI_RAY_COUNT_32, @@ -990,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; @@ -1411,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; @@ -1443,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/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_class_db.h b/tests/test_class_db.h index 11bf95ae28..b1440b83ef 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,10 @@ 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), "'."); } else { 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 +351,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,7 +363,7 @@ 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), "'."); } } } @@ -378,7 +373,7 @@ void validate_method(const Context &p_context, const ExposedClass &p_class, cons 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 + "'."); + "Method return type is a singleton: '", p_class.name, ".", p_method.name, "'."); } for (const List<ArgumentData>::Element *F = p_method.arguments.front(); F; F = F->next()) { @@ -387,10 +382,10 @@ 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, "'."); } else { 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 +407,10 @@ 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, "'."); } else { 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 +421,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 +431,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 +514,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 +552,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 +579,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 +630,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 +718,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 +737,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 +816,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 +826,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_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..2697eb6399 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -46,9 +46,12 @@ #include "test_geometry_2d.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" 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_physics_3d.cpp b/tests/test_physics_3d.cpp index a11140cfc3..f991fd7c86 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; @@ -115,7 +115,7 @@ protected: 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); @@ -211,8 +211,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 +253,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 +312,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); 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_string.h b/tests/test_string.h index 17a2df190d..cc3152203e 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") { 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/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. |